home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / utils / fdate93a.zip / FDATE.DOC < prev    next >
Text File  |  1996-04-19  |  147KB  |  3,727 lines

  1. FDATE                     Version 9.3a               1996 Apr 19
  2. ======================================================================
  3. "Everything you'd ever want to do with dates in batch files"
  4. ======================================================================
  5.  
  6. AUTHOR:     Stephen Ferg             
  7.             608 N. Harrison Street
  8.             Arlington, VA 22203-1416
  9.             USA
  10.  
  11.             telephone (voice, not FAX): (703) 525-2241
  12.             CompuServe ID             : 73377,1157
  13.             Internet                  : 73377.1157@compuserve.com
  14.                                       : Ferg_S@bls.gov
  15.  
  16. =======================================================================
  17.  
  18. If you are planning to use Fdate with Windows NT, please see the section
  19. "/V WHEN RUNNING UNDER WINDOWS NT" (below), or read file FDATE_NT.DOC,
  20. which contains the same material.
  21.  
  22.  
  23. WHAT TO DO IF THIS DOCUMENTATION SEEMS TOO OVERWHELMING
  24. ========================================================
  25.  
  26. As Fdate has grown in functionality over the years, its documentation has
  27. also grown.  Lately I've been getting feedback from people who encounter
  28. Fdate for the first time, telling me that Fdate's documentation is so
  29. massive that it is overwhelming: they have no idea where to start, or how
  30. to use the documentation to help them figure out how to make Fdate do what
  31. they need to do.
  32.  
  33. If that is the situation you're in right now, take heart!  There is hope!
  34.  
  35. To help you get started using Fdate, I've created a much shorter file
  36. called FDATEBEG.DOC (FDATE beginners documentation), which shows how to use
  37. Fdate to do the things most users want to do.
  38.  
  39. So if you're trying to use Fdate for the first time, and feeling
  40. overwhelmed (or even if you're not feeling overwhelmed), I suggest that you
  41. read FDATEBEG.DOC.
  42.  
  43.                              Table of Contents
  44.  
  45. Page numbers in the WordPerfect version of FDATE.DOC (which is not
  46. distributed with FDATE) are lost in the conversion to ASCII format. 
  47. Nevertheless, these page numbers give you a rough idea of the relative
  48. locations of the different sections.
  49.  
  50.   WHAT TO DO IF THIS DOCUMENTATION SEEMS TOO OVERWHELMING . . . . . . .   1
  51.   WHAT IS FDATE?. . . . . . . . . . . . . . . . . . . . . . . . . . . .   5
  52.      OTHER UTILITIES NAMED "FDATE". . . . . . . . . . . . . . . . . . .   6
  53.      OVERVIEW OF PARAMETERS . . . . . . . . . . . . . . . . . . . . . .   7
  54.      OVERVIEW OF FUNCTIONS. . . . . . . . . . . . . . . . . . . . . . .   9
  55.   FUNCTIONS: DETAILED DESCRIPTIONS. . . . . . . . . . . . . . . . . . .  11
  56.      DATE FORMATTING FUNCTIONS. . . . . . . . . . . . . . . . . . . . .  11
  57.      DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . . . . . .  12
  58.      MONTH DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . . .  13
  59.      WEEKDAY DATE ARITHMETIC FUNCTIONS. . . . . . . . . . . . . . . . .  14
  60.      DATE/TIME COMPARISON FUNCTIONS . . . . . . . . . . . . . . . . . .  16
  61.      COMPARE-FUNCTION ERRORLEVELS . . . . . . . . . . . . . . . . . . .  16
  62.      NUMERIC ARITHMETIC FUNCTIONS . . . . . . . . . . . . . . . . . . .  17
  63.      DATE VALIDATION FUNCTION . . . . . . . . . . . . . . . . . . . . .  19
  64.   STRING FUNCTIONS. . . . . . . . . . . . . . . . . . . . . . . . . . .  20
  65.      GET and GETU (GET USER INPUT) FUNCTION . . . . . . . . . . . . . .  20
  66.      GETK (GET KEYPRESS) FUNCTION . . . . . . . . . . . . . . . . . . .  21
  67.        Specifying the Keymask . . . . . . . . . . . . . . . . . . . . .  21
  68.        GetK Results also in ERRORLEVEL. . . . . . . . . . . . . . . . .  22
  69.        Modifying the Keymask. . . . . . . . . . . . . . . . . . . . . .  23
  70.        Displaying a User Prompt With GETK . . . . . . . . . . . . . . .  23
  71.      SUBSTR (SUBSTRING) FUNCTION. . . . . . . . . . . . . . . . . . . .  24
  72.      LEN (LENGTH) FUNCTION. . . . . . . . . . . . . . . . . . . . . . .  26
  73.      UPPER FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . . .  26
  74.      ECHO FUNCTION. . . . . . . . . . . . . . . . . . . . . . . . . . .  26
  75.      /J: JUSTIFYING OUTPUT. . . . . . . . . . . . . . . . . . . . . . .  27
  76.   DATE FORMATS. . . . . . . . . . . . . . . . . . . . . . . . . . . . .  29
  77.      SYMBOL CONVENTIONS . . . . . . . . . . . . . . . . . . . . . . . .  29
  78.      PSEUDODATES. . . . . . . . . . . . . . . . . . . . . . . . . . . .  30
  79.   INPUT DATE FORMATS. . . . . . . . . . . . . . . . . . . . . . . . . .  31
  80.      CALENDAR DATE INPUT FORMATS. . . . . . . . . . . . . . . . . . . .  31
  81.      BUSINESS JULIAN DATE INPUT FORMATS . . . . . . . . . . . . . . . .  32
  82.      GETTING DATE/TIME A FILE WAS CREATED . . . . . . . . . . . . . . .  33
  83.   OUTPUT DATE FORMATS . . . . . . . . . . . . . . . . . . . . . . . . .  34
  84.      DAY-OF-WEEK AND MONTH OUTPUT FORMATS . . . . . . . . . . . . . . .  36
  85.      MISCELLANEOUS OUTPUT FORMATS . . . . . . . . . . . . . . . . . . .  36
  86.      LEAP-YEAR FLAG OUTPUT FORMAT . . . . . . . . . . . . . . . . . . .  37
  87.      TIME OUTPUT FORMATS. . . . . . . . . . . . . . . . . . . . . . . .  37
  88.      BUSINESS JULIAN DATE OUTPUT FORMATS. . . . . . . . . . . . . . . .  38
  89.      ABSOLUTE DATE/TIME OUTPUT FORMATS. . . . . . . . . . . . . . . . .  39
  90.      /T: TIME OVERRIDE PARAMETER. . . . . . . . . . . . . . . . . . . .  40
  91.      /J: JUSTIFYING OUTPUT. . . . . . . . . . . . . . . . . . . . . . .  40
  92.   HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE. . . . . . . . .  41
  93.      CALL A BATCH FILE. . . . . . . . . . . . . . . . . . . . . . . . .  41
  94.      USE AN ENVIRONMENT-MANIPULATION UTILITY. . . . . . . . . . . . . .  41
  95.      FDATE'S /V PARAMETER . . . . . . . . . . . . . . . . . . . . . . .  42
  96.      /V WHEN RUNNING UNDER MICROSOFT WINDOWS. . . . . . . . . . . . . .  43
  97.      /V WHEN RUNNING UNDER WINDOWS NT . . . . . . . . . . . . . . . . .  44
  98.        Turbo Professional: "Highly Recommended" . . . . . . . . . . . .  45
  99.      /V WHEN USING 4DOS, NDOS, AND UMB. . . . . . . . . . . . . . . . .  46
  100.   FDATE'S ERROR HANDLING. . . . . . . . . . . . . . . . . . . . . . . .  47
  101.   EXAMPLES OF HOW TO USE FDATE. . . . . . . . . . . . . . . . . . . . .  48
  102.      :01 Display Fdate output on screen . . . . . . . . . . . . . . . .  48
  103.      :02 Redirect FDATE output to a file. . . . . . . . . . . . . . . .  48
  104.      :03 Put FDATE output in an environment variable using a batch file  48
  105.      :04 Put FDATE output in an environment variable using /V parm. . .  48
  106.      :05 Put FDATE output in an environment variable using STRINGS. . .  48
  107.      :06 Put FDATE output in an environment variable using GET. . . . .  48
  108.      :07 Get user input . . . . . . . . . . . . . . . . . . . . . . . .  49
  109.      :08 Get a user menu selection. . . . . . . . . . . . . . . . . . .  50
  110.      :10 Change a date from one format into another . . . . . . . . . .  51
  111.      :11 Find the difference in days between two dates. . . . . . . . .  51
  112.      :12 Find the elapsed days/hours/minutes between two date/times . .  52
  113.      :13 Find the elapsed years/months/days between two dates.. . . . .  55
  114.      :14 Determine how long it took a program to run. . . . . . . . . .  58
  115.      :15 Find years when a given date fell on a given day of the week .  59
  116.      :16 Find calendar date corresponding to a "business Julian" date .  61
  117.      :17 Set your PC's date to a business julian date . . . . . . . . .  62
  118.      :18 Determine if parm %1 contains a valid date . . . . . . . . . .  64
  119.      :19 "Roll your own" date format  . . . . . . . . . . . . . . . . .  64
  120.      :20 Find the 4th Thursday in November (Thanksgiving) . . . . . . .  65
  121.      :22 On a date, show what anniversary it is for some event. . . . .  65
  122.      :23 Show a list of holidays in a given year. . . . . . . . . . . .  65
  123.      :24 Show a list of Federal holidays in a given year. . . . . . . .  65
  124.      :25 Determine if a year is valid, and evenly divisible by 4. . . .  66
  125.      :30 Compare a file's date to today's date. . . . . . . . . . . . .  66
  126.      :31 Compare two files' date/time . . . . . . . . . . . . . . . . .  67
  127.      :32 Display a list of all files that were created/updated today. .  68
  128.      :33 Delete files more than X days old (use a batch-file subroutine) 69
  129.      :34 Get date to tell PKZIP to compress files older than 30 days. .  74
  130.      :40 Loop through an array of environment variables . . . . . . . .  75
  131.      :44 Do something on the last day (or last Friday) of the month . .  76
  132.      :45 Get information about the month prior to the current month . .  77
  133.      :46 Show the last Monday (or any other weekday) in this month. . .  77
  134.      :47 Show the last Monday in the month, for a series of months. . .  78
  135.      :50 Represent a date in 3 bytes of "extended hex" notation . . . .  79
  136.      :51 Represent a date in a short (4-byte) format (technique #1) . .  79
  137.      :52 Represent a date in a short (4-byte) format (technique #2) . .  80
  138.      :53 Convert numbers to "extended hex" (XX) format. . . . . . . . .  80
  139.      :54 Customize Fdate for a language of your choice. . . . . . . . .  81
  140.      :55 Fergian.BAT (used in the previous example) . . . . . . . . . .  82
  141.      :61 DO-ONCE: Run apps when booting for the first time of the day .  84
  142.      :62 Run specific software, depending on the day of the week. . . .  85
  143.      :63 Run a program at a specified time later in the day . . . . . .  85
  144.      :66 Change a filename to contain today's date. . . . . . . . . . .  87
  145.      :67 Change a file's name to a name that contains today's date. . .  87
  146.      :68 Change a file's name to a name containing an absolute minute .  87
  147.      :71 Extract the rightmost n characters of a string . . . . . . . .  87
  148.      :72 Left-pad a number with zeroes, or a string with spaces . . . .  87
  149.   HOW FDATE THINKS ABOUT DATES. . . . . . . . . . . . . . . . . . . . .  89
  150.      FDATE'S BUSINESS VIEW OF THE CALENDAR. . . . . . . . . . . . . . .  89
  151.      FDATE'S BASE DATE. . . . . . . . . . . . . . . . . . . . . . . . .  89
  152.      FDATE'S LEAP YEAR ALGORITHM. . . . . . . . . . . . . . . . . . . .  90
  153.      FDATE'S CENTURY-ASSUMPTION ALGORITHM . . . . . . . . . . . . . . .  91
  154.      FDATE'S IMPLEMENTATION LIMITS. . . . . . . . . . . . . . . . . . .  91
  155.   DISTRIBUTION ISSUES . . . . . . . . . . . . . . . . . . . . . . . . .  92
  156.      USE, REGISTRATION, AND DISTRIBUTION OF FDATE . . . . . . . . . . .  92
  157.      TECHNICAL SUPPORT FOR FDATE. . . . . . . . . . . . . . . . . . . .  93
  158.      WHERE TO FIND THE MOST CURRENT VERSION OF FDATE. . . . . . . . . .  93
  159.      UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS. . . . . . . . . . .  93
  160.      CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE. . . . . . . . . . . .  93
  161.      RECENT FDATE REVISION HISTORY. . . . . . . . . . . . . . . . . . .  94
  162.  
  163. WHAT IS FDATE?
  164. ==============
  165. Fdate is a utility for doing date formatting and date arithmetic in DOS
  166. batch files.  There are a number of different ways to put FDATE's output
  167. into environment variables.  Once this has been done, the environment
  168. variables can be used and manipulated in many ways in the batch file.
  169.  
  170. FDATE is freeware, or what is technically known as "zero-cost shareware". 
  171. There is no requirement to register FDATE in any way.  For more details,
  172. see the DISTRIBUTION ISSUES section.
  173.  
  174. Here are some of the things you can do with FDATE.
  175.  
  176.     accept user input from the keyboard
  177.  
  178.     retrieve today's date in a variety of formats
  179.       place today's date into a file name
  180.  
  181.     reformat dates 
  182.        Output formats include common American and European formats, or you
  183.        can "roll your own" by manipulating environment variables.  Month
  184.        and weekday names can be produced in several languages (English,
  185.        French, German, Spanish).
  186.  
  187.     calculate when certain holidays occur in a given year
  188.  
  189.     do date arithmetic
  190.       determine the date N days before/after a given date
  191.       compare two dates to determine which is earlier
  192.       compare two dates to determine how many days apart they are
  193.  
  194.     determine if a year is a leap year
  195.     determine whether a year is evenly divisible by some number
  196.  
  197.     determine what day of the week a date falls on
  198.       run certain software only on certain days of the week
  199.  
  200.     retrieve the date/time from the date/timestamp of a file
  201.     do simple integer arithmetic (add, subtract, modulus)
  202.     calculate the time a piece of software takes to run
  203.     convert a calendar date to/from a "business julian" date
  204.  
  205.     extract a substring from an environment variable
  206.     right, left, or center justify a string
  207.  
  208. ANOTHER UTILITY NAMED "FDATE"
  209. =============================
  210.  
  211. There is another shareware utility named FDATE in circulation, written by
  212. Garrett A. Wollman.  Garrett's FDATE is a kind of "touch" utility that can
  213. be used to change a file's NAME (rather than its date/time stamp) to a
  214. certain date.  The Public Software Library in Houston distributes it under
  215. the name FDATE.ZIP.  PSL distributes this [Ferg's] FDATE under the name
  216. FDATESF.ZIP.
  217.  
  218. Both FDATEs have been in circulation under the name FDATE.ZIP for too long
  219. to make it practical to change the name of either one.  All that can be
  220. done is to warn you of a potentially confusing situation.  If you see a
  221. file named FDATE.ZIP, read the description of the file to determine which
  222. FDATE it is.  Checking the version numbers may also help-- as of April
  223. 1996, Ferg's FDATE is in version 9.3; Wolman's FDATE is in version 1.2.
  224.  
  225.  
  226. OVERVIEW OF PARAMETERS
  227. ======================
  228.  
  229. FDATE accepts the following parameters:
  230.  
  231.        /F /A /B /I /O /P /S /N /D /L /V /T /Q /J /K /X
  232.  
  233. If the /F parameter is not present, FDATE displays a help screen.  
  234.      If you get FDATE's help screen when you don't expect it, you probably
  235.      forgot to specify the /F parameter or mistyped it.
  236.  
  237. Parameters can be in any order and upper or lower case.
  238.      Note that although function and format parms are not case sensitive,
  239.      they are "text sensitive".  If any characters are missing, added, or
  240.      mistyped, the parameter will be rejected.
  241.  
  242. What parameters are required (other than /F) depends on the function
  243. requested with the /F parameter.  Unnecessary parameters are simply
  244. ignored.
  245.  
  246.  
  247.  
  248. HERE IS A BRIEF SUMMARY OF WHAT EACH OF THE PARAMETERS MEANS
  249. ------------------------------------------------------------
  250.  
  251. /F   requests a particular FDATE function.  This is Fdate's most important
  252.      parameter.  See the OVERVIEW OF FUNCTIONS section, and the detailed
  253.      description of each Fdate function.
  254.  
  255. /A   For date functions, these two parameters are used to specify dates. 
  256. /B   For the ordinary arithmetic functions, these parameters are used to
  257.      specify numbers.  For date functions, if either of these parameters is
  258.      omitted, it defaults to today's date.
  259.  
  260. /D   day-of-week number (used only with W function)
  261.  
  262. /I   specifies format of input date(s)
  263.      If the /I parameter is omitted, /Imm-dd-ccyy is assumed.
  264.  
  265. /J   specifies justification, length, and pad character
  266.      If the /J parameter is omitted, no justification formatting is done.
  267.  
  268. /K   The GETK function takes a /K "keymask" parameter that tells it which
  269.      keys to accept.
  270.  
  271. /L  specifies language of output.
  272.      /Lus   US (American) English-language output
  273.      /Lfr   French-language output
  274.      /Lgr   German-language output
  275.      /Lsp   Spanish-language output
  276.      If the /L parameter is omitted, /Lus [American English] is assumed.
  277.  
  278. /N   number of days (always a number)
  279.  
  280. /O   specifies format of output date
  281.      If the /O parameter is omitted, /Od1 is assumed.
  282.  
  283. /Q   specifies a prompt string for a GET, GETU, or GETK function, or the
  284.      input string for a string-handling function (SUBSTR, LEN, UPPER).
  285.  
  286. /P   specifies a prefix string for the output
  287. /S   specifies a suffix string for the output
  288.      These optional parameters may always be specified or omitted.
  289.      They must be enclosed in single quotes, double quotes, or
  290.                   square brackets
  291.  
  292.      Note that "whitespace" will be removed from these strings, so
  293.      formatting of /P and /S strings cannot be controlled using spaces.  To
  294.      format strings, use periods or ASCII 255 (hex'ff') as filler.
  295.  
  296.        EXAMPLES
  297.           FDATE /Ff                /P"Today is "
  298.           FDATE /Fdif /B12-25-TTTT /P"It is " /S" days until Christmas"
  299.  
  300. /T   For date functions, /T overrides the time portion of the date on the
  301.      /A parm. (Note that it does NOT override the time portion of the date
  302.      on the /B parm.)  
  303.  
  304. /V   specifies that output is to be placed in an environment variable
  305.      rather than written to standard output.
  306.      If /V is specified but not followed by the name of an environment
  307.      variable, then /Vfdate is assumed, and output is placed in the FDATE
  308.      environment variable.
  309.  
  310. /X   Used only with the weekday arithmetic function (/Fw).  By default, if
  311.      if the date specified on the /A parm falls on the day of the week
  312.      specified on the /D parm, then the /A date is considered to be the
  313.      first date meeting the day-of-week criterion.  If the /X parm is
  314.      specified, then the /A date will NOT be considered to meet the
  315.      day-of-week criterion.  See the detailed discussion of weekday
  316.      arithmetic, below.
  317.  
  318. OVERVIEW OF FUNCTIONS
  319. =====================
  320.  
  321. Fdate's most important parameter is the function parameter, /F.  Here is a
  322. brief summary of the functions that may be specified on the /F parm, for
  323. example: /Fadd.  Detailed descriptions of each of the functions can be
  324. found on the next few pages.
  325.  
  326. If the /F parameter is omitted, it defaults to the null string, which
  327. causes Fdate to display its HELP screens.
  328.  
  329. f         Format the date in the /A parm into format specified in /O parm
  330.  
  331. add       Add the number of days in the /N parm to the date in the /A parm
  332.  
  333. sub       Subtract the number of days in the /N parm from the date in the
  334.           /A parm
  335.  
  336. dif       Return the number of days between dates in the /A and /B parms
  337.  
  338. w         Do date arithmetic in terms of weeks rather than days.  Using the
  339.           date in the /A parm, a number specified in the /N parm, and a
  340.           day-of-the-week number specified in the /D parm, return the date
  341.           of the /Nth /Day-of-the-week before (or after) /Adate.  
  342.  
  343. m         Do date arithmetic in terms of months rather than days.  Add the
  344.           number of months in the /N parm to the date in the /A parm.  /N
  345.           may be a negative number.
  346.  
  347. STRING-HANDLING FUNCTIONS
  348.  
  349. get       get user input from the keyboard, and produce it as output
  350.           Optionally, display a prompt string.
  351.  
  352. getu      same as get, but produce output converted to upper case
  353.  
  354. getk      get a keypress and produce it (converted to upper case)
  355.  
  356. len       produce the length of a string in the /Q parm
  357.  
  358. upper     convert the string in the /Q parm to upper case
  359.  
  360. e         Echo the strings on the /P and /S parameters.
  361.  
  362. substr    Extract a substring from the /Q parm, starting in column
  363.           specified on /A parm, for a length specified on /B parm.
  364.  
  365. DATE/TIME COMPARISON FUNCTIONS
  366.  
  367. comp      Compare the dates in the /A and /B parms. Return LT, EQ, or GT.
  368.  
  369. tcomp     Compare the times specified on the /A and /B parms.
  370.  
  371.  
  372. ORDINARY (AS OPPOSED TO DATE) ARITHMETIC FUNCTIONS
  373.  
  374.           Functions whose names begin with "#" do ordinary arithmetic, i.e.
  375.           arithmetic on numbers rather than dates.
  376.  
  377. #add      Add the integers specified on the /A and /B parms.  To do
  378.           subtraction, add a negative number to a positive number.
  379.  
  380. #dif      returns the difference between the integers specified on the /A
  381.           and /B parms. 
  382.  
  383. #comp     Compare the integers specified on the /A and /B parms.  Return
  384.           LT, EQ, or GT.
  385.  
  386. #mod      Modulus.  Divide the integer on the /A parm by the integer on the
  387.           /B parm, and return the remainder.  
  388.  
  389. #mult     Multiply the integer on the /A parm by the integer on the /B
  390.           parm, and return the result.
  391.  
  392. #div      Divide the integer on the /A parm by the integer on the /B parm,
  393.           and return the result as a decimal number with two decimal
  394.           places.
  395.  
  396. #idiv     Integer division. Divide the integer on the /A parm by the
  397.           integer on the /B parm, and return the result as an integer.
  398.  
  399. #2xx      Convert an integer in the range of 0-35 to "extended hex" (XX)
  400.           notation.
  401.  
  402. FUNCTIONS: DETAILED DESCRIPTIONS
  403. ================================
  404.  
  405.  
  406. DATE FORMATTING FUNCTIONS
  407. =========================
  408.  
  409. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat
  410. --------  -------------------------------------------
  411. format    this is a synonym for function "f"
  412.  
  413. f         returns /Adate in format specified by /Oformat
  414.           Since /Aformat and /Oformat can be different, the FORMAT
  415.           function is used to change a date from one format to another.
  416.           Because of the wide variety of output formats, the FORMAT
  417.           function can also be used to determine the day of week of the
  418.           date, whether the date is in a normal or leap year, etc.
  419.  
  420. EXAMPLES
  421.           FDATE /Ff /A19920101 /Iccyymmdd /O"mn zd, ccyy"
  422.           FDATE /Ff       /Atoday         /Od1
  423.           FDATE /Fformat  /Atoday         /Od1
  424.           FDATE /Ff /If /Afdate.exe /P"FDATE.EXE last updated: " /Ofull
  425.  
  426. DATE ARITHMETIC FUNCTIONS
  427. =========================
  428.  
  429. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  430. which means that Fdate can accept numbers up to 9 digits long.
  431.  
  432. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  433. --------  -------------------------------------------
  434. add       Adds      /Ndays to   /Adate, produces date in /Oformat format
  435. sub       Subtracts /Ndays from /Adate, produces date in /Oformat format
  436.  
  437.           EXAMPLES
  438.           FDATE /Fadd /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  439.           FDATE /Fsub /N90 /A01-01-1992 /Imm-dd-ccyy /Od1
  440.           FDATE /Fadd /N90 /Atoday                   /Od1
  441.  
  442. dif       Returns number of days between /Adate and /Bdate
  443.           Order of the two dates is not significant.
  444.  
  445.           NOTE THAT:
  446.           For DIF, both dates must be in the SAME format, the input format
  447.           specified in /Iformat.  If the two dates are not in the same
  448.           format, you must first reformat one of the dates using the /Ff
  449.           function, then use DIF to get their difference.
  450.  
  451.           EXAMPLES
  452.           FDATE /Fdif /A01-01-1992 /B11-11-1992  /Imm-dd-ccyy
  453.           FDATE /Fdif /A11-11-1992 /B01-01-1992  /Imm-dd-ccyy
  454.           FDATE /Fdif /Atoday      /B01-01-1992  /Imm-dd-ccyy
  455.  
  456. MONTH DATE ARITHMETIC FUNCTIONS
  457. ===============================
  458.  
  459. FUNCTION  FDATE /Ffunc /Nnumdays /Adate /Iformat /Oformat
  460. --------  -------------------------------------------
  461. m         [month arithmetic]
  462.  
  463.           This function adds /N months to /Adate, and produces a date in
  464.           /Oformat format.  It can be used to do monthly subtraction by
  465.           making the number in the /N parameter a negative number.
  466.  
  467.           EXAMPLES
  468.  
  469.           FDATE /Fm /N1  /A03-15-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  470.                   produces:   04-15-1992
  471.  
  472.           FDATE /Fm /N-1 /A03-30-1991 /Imm-dd-ccyy /Omm-dd-ccyy
  473.                   produces:   02-28-1991
  474.  
  475.           FDATE /Fm /N-1 /A03-30-1992 /Imm-dd-ccyy /Omm-dd-ccyy
  476.                   produces:   02-29-1992
  477.  
  478.  
  479.           Note that a too-simple algorithm for month arithmetic can produce
  480.           non-existent dates.  Subtracting a month from March 30, 1991 (as
  481.           in the second example) could produce a result of February 30,
  482.           1991, a date which cannot exist.  
  483.  
  484.           Fdate's month arithmetic is more sophisticated than that.  If
  485.           Fdate finds that a simple month-arithmetic operation produces an
  486.           invalid date, it subtracts the minimum number of days required to
  487.           produce a valid date.  
  488.  
  489.           Thus, in the second example, it produces February 28, 1991, the
  490.           last date in February, 1991.  In the third example, it produces
  491.           February 29, 1992 because 1992 is a leap year.  
  492.  
  493.  
  494. Note that telling Fdate to add 12 months to February 29, 1992 produces a
  495. result of February 28, 1993, since 1993 is not a leap year.  See Peter G.
  496. Neumann's INSIDE RISKS column in COMMUNICATIONS OF THE ACM, June 1992 (Vol.
  497. 35, No. 6), entitled "Leap-Year Problems":
  498.  
  499.   Prime Computer's MAGSAV failed at midnight [on Feb 29, 1992]...  G. M.
  500.   Lack noted that MAGSAV probably failed on leap-day because it tried to
  501.   increment the year by one to set a tape label expiration date, and the
  502.   resulting nonexistent date of Feb 29, 1993 threw it for a loop.
  503.  
  504. WEEKDAY DATE ARITHMETIC FUNCTIONS
  505. =================================
  506.  
  507. FUNCTION  FDATE /Ffunc /Adate /Iformat /Oformat /Ddow#  /Ndow-count
  508. --------  -----------------------------------------------------------
  509. w         [week arithmetic]
  510.           This function provides a way of doing date arithmetic in terms of
  511.           weeks rather than days.
  512.  
  513.           This function accepts a date specification in parm /A and
  514.           returns the date of the /Nth /Day-of-the-week
  515.           before or after /Adate.  For example:
  516.  
  517.           If    /A specifies November 14, 1992
  518.                 /D specifies the number for Thursday (i.e., 5)
  519.                 /N specifies a week count of 3
  520.           then /Fw returns the date of the third Thursday after
  521.           November 14, 1992. (See full example, below)
  522.  
  523.           Note that /N may be negative.  If, in the above example, /N
  524.           is specified as -3, then Fdate returns the date of the third
  525.           Thursday BEFORE November 14, 1992.
  526.  
  527.           The acceptable values for /N (number of weeks) is in
  528.           the range of 99..-99.  A value of zero (i.e. /N0) is invalid.
  529.  
  530.   A BIT OF TRICKINESS WITH WEEKDAY ARITHMETIC  
  531.      There is a small dilemma inherent in the notion of weekday arithmetic. 
  532.      If the date specified on the /A parm falls on the same day of the week
  533.      (say, Thursday) as the day of the week that was specified on the /D
  534.      parm, should (or should not) the /A date be considered the first date
  535.      that meets the day-of-week criterion?  For example, if day X is a
  536.      Thursday, and we specify that we want the first Thursday ("/N1 /D5")
  537.      from day X, should we get day X itself, or the Thursday that is 7 days
  538.      after day X? 
  539.  
  540.      Depending on what you're trying to do, one or the other kind of
  541.      behavior will be preferable.  Starting with version 9.2, FDATE
  542.      supports both kind of processing.  When using the weekday arithmetic
  543.      function (/Fw), you can determine the kind of processing that takes
  544.      place by specifying (or omitting) the /X (exclude) parm.  That is, if
  545.      the date specified on the /A parm falls on the day of the week
  546.      specified on the /D parm, then...
  547.  
  548.      IF THE /X PARM IS NOT PRESENT ...
  549.      then the /A date will be considered to be the first date meeting the
  550.      day-of-week criterion.  For example, suppose that /D specified
  551.      Thursday and /A specified Thursday, November 14, 1992.  If /N was 1 or
  552.      -1, then the output date would be the same as the input date, i.e.
  553.      Thursday November 14, 1992.
  554.  
  555.      IF THE /X PARM IS PRESENT ...
  556.      then the /A date will be EXCLUDED from consideration when looking for
  557.      the first day to meet the day-of-week criterion.  For example, suppose
  558.      that /D specified Thursday and /A specified Thursday November 14,
  559.      1992.  If /N was 1, then the output date would be the following
  560.      Thursday, November 21, 1992.  If /N was -1, then the output date would
  561.      be the preceding Thursday, November 7, 1992.
  562.  
  563.  
  564. EXAMPLES
  565.      find date of Thanksgiving (4th Thursday in November) in 1992
  566.          FDATE /Fw /A11-01-1992 /Imm-dd-ccyy /D5 /N4 /Od1
  567.      returns: Thursday November 26, 1992
  568.  
  569.      find the beginning of the work-week (Monday, 2nd day of week)
  570.      AFTER Thanksgiving, 1992
  571.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N1 /Od1
  572.  
  573.      find the beginning of the work-week (Monday, 2nd day of week)
  574.      BEFORE Thanksgiving, 1992
  575.          FDATE /Fw /A11-26-1992 /Imm-dd-ccyy /D2 /N-1 /Od1
  576.  
  577.      find last Friday's date (even if today is Friday)
  578.         FDATE /Fw /At /D6 /N-1 /X  /P"Last Friday was: "
  579.  
  580. DATE/TIME COMPARISON FUNCTIONS
  581. ==============================
  582.  
  583. FUNCTION  FDATE /Ffunc /Adate /Bdate /Iformat
  584. --------  -------------------------------------------
  585. comp      compares the dates (time granularity = 1 day)
  586.           specified on the /A and /B parms.
  587.           returns         when
  588.             LT            /A  is less than    (earlier than) /B
  589.             EQ            /A  is equal to     (same as)      /B
  590.             GT            /A  is greater than (later than)   /B
  591.  
  592.           In addition, the errorlevel is set to a special value:
  593.             LT = 101     EQ = 102     GT = 103
  594.  
  595.  
  596.  
  597. tcomp     compares the times (time granularity = 1 second)
  598.           specified on the /A and /B parms.
  599.           This is useful when input format /If (file) is specified.
  600.           It can be used to compare the timestamps of two files and
  601.           determine which is older.
  602.               EXAMPLE: Fdate /Ftcomp /If /Amyfile.1 /Byourfile.1
  603.  
  604.           returns         when
  605.             LT            /A  is less than    (earlier than) /B
  606.             EQ            /A  is equal to     (same as)      /B
  607.             GT            /A  is greater than (later than)   /B
  608.  
  609.           In addition, the errorlevel is set to a special value:
  610.             LT = 101     EQ = 102     GT = 103
  611.  
  612.  
  613.  
  614. COMPARE-FUNCTION ERRORLEVELS
  615. ============================
  616.  
  617. Starting with version 8.3, Fdate's "comparison" functions (comp, tcomp,
  618. #comp) return distinct errorlevels as well as distinct output strings:
  619.  
  620.           returns         errorlevel
  621.             LT            101
  622.             EQ            102
  623.             GT            103
  624.  
  625. NUMERIC ARITHMETIC FUNCTIONS
  626. ============================
  627.  
  628. Note that all of Fdate's arithmetic functions operate on integers.  A
  629. decimal number on an input parameter will be rejected, and an error message
  630. will be displayed.
  631.  
  632. FUNCTION  FDATE /Ffunc /Anum  /Bnum
  633. --------  -------------------------------------------
  634.  
  635. #add      returns the sum of the integers specified
  636.           on the /A and /B parms.  Can be used to calculate the
  637.           "absolute" minute(second, date) in the future from a given
  638.           "absolute" minute(second, date).   Also useful in generating
  639.           sequences of numbers and looping (see EXAMPLES).
  640.  
  641. #sub      (not supported)
  642.           Fdate does not provide a numeric subtraction operation as such. 
  643.           To do subtraction, add two numbers, one of which is a negative
  644.           number.  For example, to subtract 3 from 2:
  645.               FDATE /F#add /A2 /B-3          [ returns: -1 ]
  646.  
  647. #dif      returns the difference between the integers specified on the /A
  648.           and /B parms.  #dif is the same as subtraction in which the
  649.           smaller number is subtracted from the larger number; it will
  650.           never return a negative number.  It can be used to calculate the 
  651.           number of minutes(seconds, days) between two "Absolute"
  652.           minutes(seconds, dates).
  653.  
  654. #comp     compares the integers specified on the /A and /B parms.
  655.           returns         when
  656.             LT            /A  is less    than /B
  657.             EQ            /A  is equal   to   /B
  658.             GT            /A  is greater than /B
  659.  
  660.           In addition, the errorlevel is set to a special value:
  661.             LT = 101     EQ = 102     GT = 103
  662.  
  663. #mod      divides the integer on the /A parm by the integer on the /B parm,
  664.           and returns the remainder.  
  665.  
  666.           This is useful for determining whether a number is evenly
  667.           divisible by some other number.  If the remainder is 0, then /A
  668.           is evenly divisible by /B.  If a year is evenly divisible by 4,
  669.           for example, then it is an American election year.  If it is
  670.           evenly divisible by 100, then it is a century year, etc.
  671.  
  672.  
  673. #mult     multiplies the integer on the /A parm by the integer on the /B
  674.           parm, and returns the result.
  675.  
  676. #div      (division) divides the integer on the /A parm by the integer on
  677.           the /B parm, and returns the result as a decimal number, with two
  678.           digits to the right of the decimal.
  679.  
  680.           This is useful for dividing a number (representing the number of
  681.           minutes in some period) by 60 to get the length of the period
  682.           expressed in terms of hours, or by 1440 to get the length of the
  683.           period expressed in terms of days.  Or you could divide a number
  684.           of days by 7 to get the number of weeks, etc.
  685.  
  686.  
  687. #idiv     (integer division) divides the integer on the /A parm by the
  688.           integer on the /B parm, and returns the result as an integer.
  689.  
  690.           This is useful, especially in conjunction with the #mod function,
  691.           for converting a number of minutes into a number of hours and
  692.           minutes, or days and hours and minutes.  See the EXAMPLES
  693.           section, below.
  694.  
  695. #2xx      (convert number to "extended hex" format)
  696.           "Extended hexadecimal" (XX) notation uses all of the digits, and
  697.           all of the letters of the alphabet, to express numbers in the
  698.           range of 0 to 35 as a single character.  
  699.  
  700.           This function takes a number supplied on parameter /A, and
  701.           returns a single character in extended hex notation.  The input
  702.           number should be in the range of 0-35.  A number of less than 0
  703.           or larger than 35 is rejected as an error (returns "ERROR" and
  704.           errorlevel of 1).
  705.  
  706.           EXAMPLE: Fdate /F#2xx /A35    =====> returns the letter Z
  707.  
  708. DATE VALIDATION FUNCTION
  709. ========================
  710.  
  711. v    If the date specified on the /A parm is valid, produces "" (the null
  712.      string).  Otherwise, produces "ERROR" and a non-zero errorlevel by
  713.      triggering Fdate's error-handling function.  (See the section on
  714.      FDATE'S ERROR HANDLING, later in this documentation.)
  715.  
  716.      When using the /Fv parameter, you will almost always want to check
  717.      success of the date validation by checking the errorlevel, and to
  718.      redirect Fdate's output to NUL (so that when it writes the null
  719.      string, it does not produce a blank line on your screen).
  720.  
  721.      When processing an input date, Fdate does not reject all invalid
  722.      dates: specifically, it is very forgiving about the number in the day-
  723.      of-the-month part of input dates.  It will accept, for example,
  724.      19931144 (November 44, 1993 in CCYYMMDD format) and process it quite
  725.      happily (as December 14, 1993).  This is not a bug, it is a feature. 
  726.      This feature provides one way (admittedly a crude one) of doing date
  727.      arithmetic.  The date part (JJJ) of a Business Julian input date can
  728.      be used in the same way.  
  729.  
  730.      This feature can be a drawback, however, if you want to be sure that
  731.      some date (say a date that a user entered as an input parameter) is
  732.      valid.  The /Fv function provides a way of completely checking a date
  733.      for validity.  It will, for example, reject November 44, 1993 as
  734.      invalid. 
  735.  
  736.  
  737. STRING FUNCTIONS
  738. ================================
  739.  
  740. GET and GETU (GET USER INPUT) FUNCTIONS
  741. =======================================
  742.  
  743. get  get user input
  744. getu get user input (uppercase)
  745.  
  746.      These functions wait for the user to enter an input string, terminated
  747.      by a press of the ENTER key.  Then Fdate simply produces that same
  748.      input string (or in the case of GETU, that input string in all upper
  749.      case) as its output.  
  750.  
  751.      If the /Q prompt-string parameter is specified, then the prompt string
  752.      is displayed, but a NEWLINE is not written to the screen before
  753.      waiting for the user's input.
  754.  
  755.      As with Fdate's other forms of output, this output can be displayed,
  756.      redirected to a file, or (if your environment supports Fdate's /V
  757.      parameter) placed into an environment variable.
  758.  
  759.      This "get" function provides no edit mask for input -- Fdate will
  760.      accept anything.  The situation is helped by the fact that Fdate also
  761.      provides a validate function (/Fv) which can be used to validate the
  762.      user input, so that one can:
  763.  
  764.           1.   use /Fget to get user input and place it in an environment
  765.                variable 
  766.           2.   use /Fv to validate the date in the Evar
  767.           3.   use the rest of the batch file to process the user input
  768.  
  769.      See examples: "Get user input" and FORATIM2.BAT
  770.  
  771.      For a program that provides more sophisticated functions for getting
  772.      user input in batch files (type checking, edit masks, etc.), I
  773.      recommend Bob Stephan's shareware program GET, which is described
  774.      elsewhere in this documentation.
  775.  
  776. GETK (GET KEYPRESS) FUNCTION
  777. =======================================
  778. getK get keypress 
  779.  
  780.      This function waits for the user to press an acceptable key, then
  781.      produces the key as its output.  If the key pressed is a letter, then
  782.      the letter is returned IN UPPER CASE.  This feature is designed to
  783.      support simple "pick a menu selection" processing in batch files.
  784.  
  785.      The GETK function takes a /K "keymask" parameter that tells it which
  786.      keys to accept.  If the user presses an unacceptable key (i.e. one
  787.      that is not in the keymask), the keypress is ignored.
  788.  
  789.      If no /K parm is specified, the default keymask is:
  790.              ABCDEFGHIJKLMNOPQRSTUVWXYZx
  791.      That is, the default keymask will accept letters and the ESCAPE key.
  792.  
  793.   Specifying the Keymask
  794.  
  795.      NOTE THAT THE VALUES SPECIFIED ON THE /K PARM ARE CASE-SENSITIVE.  
  796.  
  797.      The keymask may contain numbers, uppercase letters, and any of the
  798.      other printable characters on the keyboard.  
  799.  
  800.      There is no way to tell FDATE to accept "special" keypresses such as
  801.      function keys, ALT or CONTROL keys, arrow keys, etc.
  802.  
  803.      If the keymask contains an uppercase letter (e.g. "A"), and the user
  804.      presses the corresponding unshifted letter (e.g. "a"), then the
  805.      keypress will be accepted and the uppercase letter will be returned.
  806.  
  807.      The keymask may contain the following lowercase letters, which have
  808.      special meanings:
  809.  
  810.        x  represents the ESCAPE key
  811.        e  represents the ENTER (RETURN) key
  812.        z  [a place-holder character]
  813.  
  814.             Lowercase "z" will be ignored when FDATE decides which
  815.             keypresses are acceptable.  Its presence in the keymask will
  816.             affect the positions of other characters in the keymask, and
  817.             hence the ERRORLEVEL that FDATE returns when the user presses
  818.             an acceptable key.  (For the uses of "z", see "GetK Results
  819.             also in ERRORLEVEL" and "Modifying the Keymask", below.)
  820.  
  821.      All other lowercase letters are reserved for possible future use.  In
  822.      the current release of FDATE, they are treated like lowercase "z".
  823.  
  824.      EXAMPLE:  If a keymask of "/kXx" was specified, then if the user
  825.                pressed the (shifted or unshifted) "X" key, then uppercase
  826.                "X" would be returned.  If he pressed the ESCAPE key, then
  827.                lowercase "x" would be returned.
  828.  
  829.   GetK Results also in ERRORLEVEL
  830.  
  831.      When the GETK function returns a key, it sets the DOS errorlevel to a
  832.      value corresponding to the position of that key in the keymask.  For
  833.      example, with keymask of "/kABx", if the user presses:
  834.  
  835.           "A": value returned will be "A", errorlevel will be 1
  836.           "B": value returned will be "B", errorlevel will be 2
  837.        ESCAPE: value returned will be "x", errorlevel will be 3
  838.  
  839.      If the user presses CONTROL+BREAK, FDATE will abort and return
  840.      errorlevel 255.
  841.  
  842.      Here is an example batch file:
  843.      ==================================================================
  844.      @echo off
  845.      cls
  846.      echo Demonstration of FDATE's GETK (get keypress) function
  847.      echo Press CONTROL+BREAK to end
  848.      :top
  849.      echo.
  850.      fdate /fGetK /P"You pressed: " /Q"Press a key: "  /K"12ABxe "
  851.      if errorlevel 1  if not errorlevel 2  echo errorlevel : 1
  852.      if errorlevel 2  if not errorlevel 3  echo errorlevel : 2
  853.      if errorlevel 3  if not errorlevel 4  echo errorlevel : 3
  854.      if errorlevel 4  if not errorlevel 5  echo errorlevel : 4
  855.      if errorlevel 5  if not errorlevel 6  echo errorlevel : 5
  856.      if errorlevel 6  if not errorlevel 7  echo errorlevel : 6
  857.      if errorlevel 7  if not errorlevel 8  echo errorlevel : 7
  858.      if errorlevel 255 echo ERRORLEVEL 255
  859.      if errorlevel 255 goto endit
  860.      goto top
  861.      :endit
  862.      ==================================================================
  863.  
  864.      Note that the keymask may contain blanks if the keymask is enclosed in
  865.      quotes (as in this example batch file).  But remember that Fdate
  866.      eliminates redundant spaces when obtaining its parameter input, so you
  867.      should never include more than one blank in your keymask.
  868.  
  869.   Modifying the Keymask
  870.  
  871.      It is often necessary to make program modifications during the life of
  872.      a batch file.  If you are using the GETK function and testing the
  873.      errorlevel rather than the environment, then the insertion or deletion
  874.      of characters into the existing keymask will change the errorlevels
  875.      returned by the following characters in the keymask.  This will force
  876.      you to re-write the errorlevel tests, which may be a big job if the
  877.      keymask is long.
  878.  
  879.      Here are some tips on how to avoid this work:
  880.  
  881.          When ADDING a character to the keymask, always add it at the END
  882.           of the keymask.
  883.  
  884.          When DELETING a character from the keymask, do not actually
  885.           delete it.  Instead, replace it by a lowercase "z".
  886.  
  887.  
  888.  
  889.   Displaying a User Prompt With GETK
  890.  
  891.      The /Q (user prompt) parameter is especially handy when used in
  892.      conjunction with the GETK function.  If the /Q prompt-string parameter
  893.      is specified (as in the example batch file, above), then the prompt
  894.      string is displayed, but a NEWLINE is not written to the screen before
  895.      waiting for the user's keypress.
  896.  
  897.      For a program that provides more sophisticated "get key" functions for
  898.      batch files, I recommend Bob Stephan's shareware program GET, which is
  899.      described elsewhere in this documentation.
  900.  
  901. SUBSTR (SUBSTRING) FUNCTION
  902. ===============================
  903.  
  904. substr
  905.      This function returns a substring of the string supplied in the /Q
  906.      parm, starting in the column supplied in the /A parm, for a length
  907.      supplied in the /B parm.  
  908.  
  909.      The start column specified in the /A parm may be a negative number; if
  910.      it is, then the start column is calculated from the end of the string
  911.      rather than from the beginning.  This feature makes it easy to extract
  912.      the rightmost characters of a string.  
  913.  
  914.                Specifically, when the ParmA is negative, the start position
  915.                is calculated using the following formula:
  916.  
  917.                       StartColumn = length(ParmQ) + 1 + ParmA
  918.  
  919.                Example:   Fdate /Fsubstr  /A-2  /Qabcd
  920.                       StartColumn = length(ParmQ) + 1 + ParmA
  921.                       StartColumn =      4        + 1 + (-2)     = 3  
  922.  
  923.      If /Q is omitted, Fdate reports an error.
  924.  
  925.      If /A is zero, Fdate reports an error.
  926.      If /A is omitted, it defaults to 1 (that is, the start of the string).
  927.      If /A is negative,  and longer than the length of the string, then the
  928.                          start column is 1 (the start of the string)
  929.  
  930.      If /B (length) is so great that it exceed the length of the /Q input
  931.      string, then only the remainder of the string is returned.
  932.  
  933.      If /B is zero, Fdate returns a null string.
  934.      If /B is omitted, it defaults to 999.
  935.  
  936.      EXAMPLES:
  937.           Fdate /Fsubstr /A7 /B2 /Q"STEVE FERG"   ===> "FE"
  938.           Fdate /Fsubstr /A7     /Q"STEVE FERG"   ===> "FERG"    
  939.           Fdate /Fsubstr     /B5 /Q"STEVE FERG"   ===> "STEVE"   
  940.  
  941.      EXAMPLES using a negative start position:
  942.           Fdate /Fsubstr /a-6 /B3 /Q"1994 Jun 03"   ===> "Jun         
  943.  
  944.           rem extract the rightmost 6 characters of a string
  945.           Fdate /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"     
  946.  
  947.           rem pad YEAR environment variable to the left with zeroes, 
  948.           rem to make sure it is 4 bytes long
  949.           Fdate /Fsubstr /A-4 /q0000%year% /vyear
  950.  
  951.  
  952.      REMEMBER that Fdate eliminates redundant spaces when obtaining its
  953.      parameter input:
  954.  
  955.           Fdate /Fsubstr /A7     /Q"STEVE FERG"      ===> "FERG" 
  956.           Fdate /Fsubstr /A7     /Q"STEVE  FERG"     ===> "FERG" 
  957.           Fdate /Fsubstr /A7     /Q"STEVE    FERG"   ===> "FERG" 
  958.  
  959. LEN (LENGTH) FUNCTION
  960. =====================
  961.  
  962. len       Produces a number that is the length of the string on the /Q
  963.           parm.
  964.  
  965.  
  966. UPPER FUNCTION
  967. ===============
  968.  
  969. upper     Produces the string on the /Q parm, converted to upper case.
  970.  
  971.  
  972.  
  973. ECHO FUNCTION
  974. =============
  975.  
  976. e         Produces only the strings specified using the /P and /S
  977.           parameters.
  978.  
  979. You can use /Fe for situations in which you want Fdate to produce output
  980. that doesn't include any sort of date.  In these cases, Fdate functions
  981. just like the DOS "echo" command.  
  982.  
  983. The /Fe function is especially useful in conjunction with the /J (justify)
  984. parm (see below).
  985.  
  986. One nifty feature of /Fe (although one that will be of interest only to
  987. extreme batch-file power users) is its ability, when used in conjunction
  988. with /V, to put a character into an environment variable that the SET
  989. command would not accept: characters such as an equal-sign "=" , the
  990. redirection symbol ">", and the pipe symbol "|".
  991.  
  992. /J: JUSTIFYING OUTPUT
  993. ==========================
  994. Using the /J (justify) parameter, it is possible to right, center, or left-
  995. justify FDATE's output, truncate it, or pad it with a certain character.   
  996.  
  997. Note that /J is not a function, but a parameter.  The /J parameter may be
  998. used in conjunction with any of FDATE's functions.  (It is discussed here,
  999. with the string-handling functions, because that's where it seemed most at
  1000. home.)
  1001.  
  1002. Justification takes place AFTER the strings specified on the /P (prefix)
  1003. and /S (suffix) parms have been added to the output.
  1004.  
  1005. The format of the /J parm is:      /J"tp##"         where
  1006.  
  1007.   t is a single character indicating the type of justification desired:
  1008.        R  right
  1009.        L  left
  1010.        C  centered
  1011.  
  1012.   p  is a single character specifying the character to be used to pad the
  1013.      output out to the desired length.  The most common values for this
  1014.      character will be the period (".") and the blank.  In order for a
  1015.      blank to be recognized as a pad character (and not to be taken as the
  1016.      terminator of the /J-parm value), the /J-parm value must be enclosed
  1017.      in single or double quotes, e.g.:   /J"C 79"
  1018.  
  1019. ##   is a number that specifies the length of the field within which
  1020.      justification should take place.  This must be a number between 1 and
  1021.      240.
  1022.  
  1023.      If ## is less than the length of the un-justified output string, then
  1024.      the un-justified output string will be truncated to ## characters,
  1025.      starting at the point specified by the justification type (i.e. at the
  1026.      right, left, or center of the un-justified output string).
  1027.  
  1028.  
  1029. SOME USES FOR THE /J PARM  
  1030.  
  1031.   (Most of these uses are illustrated in HOLIDAYS.BAT, which is included
  1032.   in the FDATE distribution ZIP file.)
  1033.  
  1034.   In conjunction with the "echo" function (/Fe), the /J parm can be used
  1035.   to justify any value that you wish, not just output dates created by
  1036.   Fdate.  Put the value to be justified in the /P (prefix) parm and/or the
  1037.   /S (suffix) parm.  Put a title, for example, as the value of the /P
  1038.   parm, and specify center justification, padded with spaces, to a length
  1039.   of 79 characters (/J"c 79").  This will display the title, centered on
  1040.   the screen.
  1041.  
  1042.   If you use the "echo" function and the /J parm, and specify the /P or /S
  1043.   parm but do not specify values for them, then only the pad character
  1044.   will be displayed. (That is, the null string will be padded with the pad
  1045.   character to the desired length.) 
  1046.  
  1047.      EXAMPLE:  This is a handy way to draw horizontal lines of dashes,
  1048.                dots, or any other desired character.
  1049.                          FDATE  /Fe  /P  /JC-79 
  1050.  
  1051.   The /J parm can be used to left-pad a number with zeroes.
  1052.  
  1053.      EXAMPLE:  Many of Fdate's input formats require the year to be in
  1054.                complete 4-digit CCYY format.  If your batch file obtains a
  1055.                value for YEAR from the user, the user might enter a YEAR
  1056.                that is less than 1000.  You can add leading zeroes to YEAR
  1057.                by right justifying it, padded it with '0' to a length of 4. 
  1058.                
  1059.                     FDATE  /Fe  /P%year%  /JR04  /vyear
  1060.  
  1061.   Because /J can be used to truncate a string to a specified length, it
  1062.   can be used to extract the rightmost, leftmost, or centermost ##
  1063.   characters of a string. 
  1064.  
  1065.  
  1066. EXAMPLES
  1067.  
  1068.   Fdate /Fe /J"C 79" /P"SCREEN TITLE"
  1069.      Fdate's output is not put into an environment variable, so it will be
  1070.      displayed on the screen.  This command will echo the string "SCREEN
  1071.      TITLE" to the screen, centered in a field 79 characters long (that is,
  1072.      centered on the screen), and padded to the left and right with blanks.
  1073.  
  1074.   Fdate /Fe /J"L.40" /P"Next report due date" /Vtitle
  1075.   Fdate /fadd /N60  /Od1 /p"%title% "
  1076.      The first command left-justifies "Next report due date" in a string 40
  1077.      characters wide, padded to the right with periods, and puts it into
  1078.      the TITLE environment variable.  In the second step, the TITLE
  1079.      environment variable is used as the label for a date 60 days in the
  1080.      future.  In the second step, note the space between the end of %title%
  1081.      and the trailing double-quote.  This leaves a nice space between the
  1082.      dot leader and the date.
  1083.  
  1084.   For more examples, see HOLIDAYS.BAT.
  1085.  
  1086. DATE FORMATS
  1087. ============
  1088.  
  1089. SYMBOL CONVENTIONS
  1090. ==================
  1091.  
  1092. The following symbols are used in specifying date formats:
  1093.  
  1094. SYMBOL  EXAMPLE   MEANING
  1095. ------  -------   -------------------------------------
  1096. cc        19      century
  1097. yy        93      year
  1098. mm        02      month
  1099. zm         2      month without leading zero
  1100. dd        08      day
  1101. zd         8      day   without leading zero
  1102. mn       February month name
  1103. mn3      Feb      month name, first 3 characters only
  1104. dow      Tuesday  day of week
  1105. dow3     Tue      day of week, first 3 characters only
  1106. dow#      3       day of week as a number (Sunday=1, Monday = 2, etc.)
  1107. today             is a "pseudodate" representing the current date
  1108. t                 is an alias for the "today" pseudodate
  1109. hh:mm    09:05    hours and minutes
  1110. hhmm     0905     hours and minutes
  1111. ss        13      seconds
  1112.  
  1113.  
  1114.  
  1115. PSEUDODATES
  1116. ===========
  1117.  
  1118. t (or today)
  1119.           can be used with either /A or /B, e.g. /Atoday or /At.
  1120.           This is the default for both /A and /B.  That is, if /A is not
  1121.           specified, /At is assumed, and the same for /B.
  1122.  
  1123.           NOTE THAT
  1124.           "Today" as a date specification operates independently of any
  1125.           input format.  You need to specify an input format (either
  1126.           explicitly via the /I parameter, or implicitly by accepting the
  1127.           default value of /I) only for input dates that are supplied to
  1128.           Fdate in some other way than via the "today" pseudodate: as a
  1129.           date literal, a filename, etc.
  1130.  
  1131. EXAMPLES:
  1132.           rem Get the date that is 90 days from today
  1133.           FDATE /Fadd /N90 /Atoday /Omm-dd-ccyy
  1134.           FDATE /Fadd /N90 /At     /Omm-dd-ccyy
  1135.  
  1136.           rem determine if this year is a leapyear
  1137.           FDATE /Ff /At /OLY
  1138.  
  1139.  
  1140.  
  1141.  
  1142. tttt      When used in place of a 4-digit CCYY string, "tttt"
  1143.           will cause Fdate to use today's 4-digit year (CCYY).
  1144.  
  1145. tt        When used in place of a 2-digit DD, MM, or YY string,
  1146.           "tt" will cause Fdate to use today's day-of-the-month,
  1147.           month, or 2-digit year, respectively.
  1148.  
  1149.           Note that "tt" can NOT be used for the YY portion of a CCYY
  1150.           input year.  The following, for example, is NOT valid:
  1151.                FDATE /Ff /Imm-dd-ccyy /A01-01-19tt /Od1
  1152.  
  1153. EXAMPLES:
  1154.  
  1155.      FDATE /Ff /Imm-dd-ccyy /A01-01-tttt
  1156.      FDATE /Ff /Imm-dd-yy   /A01-01-tt 
  1157.  
  1158.      rem report the 15th day of this month, this year
  1159.      FDATE /Ff /Imm-dd-ccyy /Att-15-tttt
  1160.  
  1161.      rem Show the first Monday in the second quarter of this year
  1162.      FDATE /Fw /Iccyymmdd /Atttt0401 /D2 /N1  /P"First Monday in QTR#2: "
  1163.  
  1164.      rem Show the last Friday on/before the 15th of this month.
  1165.      FDATE /Fw /Iccyymmdd /Atttttt15 /D6 /N-1 /P"Friday before the 15th: "
  1166.  
  1167.  
  1168. INPUT DATE FORMATS
  1169. ==================
  1170.  
  1171.  
  1172. CALENDAR DATE INPUT FORMATS
  1173. ===========================
  1174.  
  1175. FORMAT      EXAMPLES      DISCUSSION
  1176. ------      ---------     -----------------------------
  1177. ccyymmdd    19922002  
  1178.  
  1179.  
  1180. On the /I (input format) parm, the separator character of the following
  1181. input formats must be a dash.  This simply tells Fdate that the input
  1182. date will contain SOME separator character.  The separator character that
  1183. actually occurs in dates in the /A and /B parms is ignored, and may be
  1184. any non-numeric character: a slash "/", a dash "-", a dot ".", etc.
  1185.  
  1186. In specifications that begin with "mm-dd" or "dd-mm", leading zeros need
  1187. not be present in the "mm" and "dd" part of the date.
  1188.  
  1189. ccyy-mm-dd  1992-02-20    Leading zeros MUST be present, since the
  1190.             1992/02/20    date does not begin with dd-mm or mm-dd.    
  1191.             1992.02.20    
  1192.  
  1193.  
  1194. mm-dd-ccyy  02-20-1992    
  1195.             02/20/1992    The dash represents ANY non-numeric character.
  1196.  
  1197.              2-5-1992     Leading zeros need not be present.
  1198.              2/5/1992
  1199.  
  1200. mm-dd-yy    02-05-92      February 5, 1992.  See discussion of
  1201.              2/5/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1202.  
  1203.                           ---------------------------------------
  1204.                           In the following formats, days
  1205.                           precede months  (European style)
  1206.                           ---------------------------------------
  1207.  
  1208. dd-mm-ccyy  05-02-1992 
  1209.             05/02/1992 
  1210.  
  1211.              5-2-1992     Leading zeros need not be present.
  1212.              5/2/1992
  1213.  
  1214. dd-mm-yy    05-02-92      February 5, 1992.  See discussion of
  1215.              5/2/92       FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1216.  
  1217. BUSINESS JULIAN DATE INPUT FORMATS
  1218. ==================================
  1219.  
  1220. These are formats for "business julian" dates: dates expressed as the
  1221. number of days from the beginning of the year, when January 1 is day 1.
  1222.  
  1223. EXAMPLES:
  1224.  
  1225.       date      BUSINESS JULIAN DATE
  1226.   -----------   --------------------
  1227.   Jan  5, 1992  92005
  1228.   Jan  5, 1993  93005
  1229.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1230.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1231.  
  1232. -----------------------------------------------------------------------
  1233. NOTE:   * JJJ can be 1 - 4 digits
  1234.         * may include a prefix of a plus or minus ( + or - ) sign
  1235. -----------------------------------------------------------------------
  1236.  
  1237. FORMAT      EXAMPLES      DISCUSSION
  1238. ------      ---------     -----------------------------
  1239. ccyyjjj     1992003       Third day of 1992, i.e. Jan 3, 1992
  1240.             19923         Third day of 1992
  1241.             tttt003       Third day of this year
  1242.             tttt3         Third day of this year
  1243.  
  1244.   yyjjj       92003       Third day of 1992
  1245.               923         Third day of 1992
  1246.               tt003       Third day of this year
  1247.               tt3         Third day of this year
  1248.               01003       Third day of 2001           See
  1249.                           FDATE'S CENTURY ASSUMPTION ALGORITHM, below
  1250.  
  1251. NOTE THAT FDATE WILL ACCEPT "JJJ" OF LESS THAN 1 & MORE THAN 366.
  1252. -----------------------------------------------------------------
  1253.  
  1254.   yyjjj       tt1000      the 1000th day from beginning of this year
  1255.               tt0         last day of last year
  1256.               tt-1        next-to-last day of last year
  1257.  
  1258. FDATE /Ff /Iccyyjjj /Od1 /A1992-1  produces... Monday December 30, 1991
  1259. FDATE /Ff /Iccyyjjj /Od1 /A19920   produces... Tuesday December 31, 1991
  1260. FDATE /Ff /Iccyyjjj /Od1 /A1992+1  produces... Wednesday January 1, 1992
  1261.  
  1262. FDATE /Ff /Iccyyjjj /Od1 /A1992366 produces... Thursday December 31, 1992
  1263. FDATE /Ff /Iccyyjjj /Od1 /A1992367 produces... Friday January 1, 1993
  1264.  
  1265. This feature allows limited date arithmetic with ordinary business
  1266. Julian days.  For example, 90 days from tt300 can be shown by:
  1267.  
  1268.                   FDATE /Ff /Iyyjjj /Att390
  1269.  
  1270. GETTING DATE/TIME A FILE WAS CREATED
  1271. ====================================
  1272.  
  1273. FORMAT      EXAMPLES      DISCUSSION
  1274. ------      ---------     -----------------------------
  1275. f           MYFILE.1      Input format F (file) tells Fdate that
  1276.                           /A and /B will specify filenames, and that
  1277.                           Fdate should pick up the input date and time
  1278.                           from the date/time stamp on a file.
  1279.  
  1280. Example: FDATE /Ff /If /Afdate.exe /P"FDATE.EXE last updated: " /Ofull
  1281.  
  1282.      Note that if you specify /If, then both /A and /B will be interpreted
  1283.      as filenames.
  1284.  
  1285.      Because the input format applies to both /A and /B parms, it is not
  1286.      possible to put a filename in /A and a date literal in /B, and then
  1287.      (say) use the "comp" or "dif" function to compare them.  You must
  1288.      first extract the file's date into an environment variable, and then
  1289.      compare that environment variable to the date literal.
  1290.  
  1291.           The only exception to this rule is the pseudodate "t" (i.e. /At
  1292.           or /Bt) which will pick up the current date and time from the
  1293.           system clock.  This feature will allow you, for example, to
  1294.           compare the date of a file to today's date (see EXAMPLES).
  1295.  
  1296.      A filename may (but need not) be fully qualified: i.e. "MYFILE.1" and
  1297.      "C:\DBASE\WORKDIR\MYFILE.1" are both acceptable.
  1298.  
  1299.      A filename may contain wildcards.  If it does, the date/time stamp
  1300.      will be retrieved from the first file that FDATE finds that meets the
  1301.      filespec.  Giving FDATE a filespec containing a wildcard is pretty
  1302.      useless, but FDATE will not reject it.
  1303.  
  1304. OUTPUT DATE FORMATS
  1305. ===================
  1306.  
  1307. FORMAT        EXAMPLES      COMMENTS
  1308. ------        ---------     -----------------------------
  1309. dd-mn3-yy     08-Feb-92     CompuServe-style date
  1310.   yy            93          2-digit year number
  1311. ccyy          1993          4-digit year number (includes century)
  1312. ccyymm        199302        useful for triggering monthly processing
  1313. ccyymmdd      19930208      useful for putting current date in filename
  1314.   yymmdd        930208      PKZIP's Japanese date format
  1315.     mmdd          0208
  1316.     mmddyy        020892    PKZIP's American date format
  1317.     mmddccyy      02081992 
  1318.       mm            02      2-digit month number
  1319.       zm             2      month number, no leading zeros
  1320.       dd            08      2-digit day-of-month number
  1321.       zd             8      day-of-month number, no leading zeros
  1322.  
  1323. In the following formats, months precede days (American style)
  1324. ------------------------------------------------------------------
  1325. mm/dd/ccyy    02/08/1993
  1326. mm-dd-ccyy    02-08-1993
  1327. mm.dd.ccyy    02.08.1993    British-style dates
  1328.  
  1329. zm/zd/ccyy     2/8/1993     no leading zeros in day or month
  1330. zm-zd-ccyy     2-8-1993     no leading zeros in day or month
  1331. zm.zd.ccyy     2.8.1993     British-style dates
  1332.  
  1333. mm/dd/yy      02/08/92
  1334. mm-dd-yy      02-08-92
  1335. mm.dd.yy      02.08.92      British-style dates
  1336.  
  1337. zm/zd/yy       2/8/92       no leading zeros in day or month
  1338. zm-zd-yy       2-8-92       no leading zeros in day or month
  1339. zm.zd.yy       2.8.92       no leading zeros in day or month
  1340.  
  1341.  
  1342. In the following formats, days precede months  (European style)
  1343. ------------------------------------------------------------------
  1344.  
  1345. ddmmccyy      02081993
  1346. ddmmyy        020893       PKZIP's European date format
  1347.  
  1348. dd/mm/ccyy    02/08/1993
  1349. dd-mm-ccyy    02-08-1993
  1350. dd.mm.ccyy    02.08.1993    British-style dates
  1351.  
  1352. zd/zm/ccyy     2/8/1993     no leading zeros in day or month
  1353. zd-zm-ccyy     2-8-1993     no leading zeros in day or month
  1354. zd.zm.ccyy     2.8.1993     British-style dates
  1355.  
  1356. dd/mm/yy      02/08/93
  1357. dd-mm-yy      02-08-93
  1358. dd.mm.yy      02.08.93      British-style dates
  1359.  
  1360. zd/zm/yy       2/8/93       no leading zeros in day or month
  1361. zd-zm-yy       2-8-93       no leading zeros in day or month
  1362. zd.zm.yy       2.8.93       British-style dates
  1363.  
  1364. DAY-OF-WEEK AND MONTH OUTPUT FORMATS
  1365. ====================================
  1366.  
  1367. dow#           5            Sunday=1, Monday=2 .... Saturday=7.
  1368.  
  1369. dow            Thursday     name of day of week
  1370.                jeudi        if /Lfr specified
  1371.                Donnerstag   if /Lgr specified
  1372.  
  1373. dow3           Thu          first 3 characters of name of day of week
  1374.                jeu          if /Lfr specified
  1375.                Don          if /Lgr specified
  1376.  
  1377. mn             February     name of month
  1378.                fevrier      if /Lfr specified
  1379.                Februar      if /Lgr specified
  1380.  
  1381. mn3            Feb          first 3 characters of name of month
  1382.                fev          if /Lfr specified
  1383.                Feb          if /Lgr specified
  1384.  
  1385.  
  1386.  
  1387. MISCELLANEOUS OUTPUT FORMATS
  1388. ============================
  1389.  
  1390. full      9:05 pm on Wednesday February 5, 1992
  1391.           9:05 pm, mercredi le 5 fevrier 1992  [/Lfr specified]
  1392.           9:05 pm, miércoles el 5 de febrero de 1992 [/Lsp specified]
  1393.           Mittwoch, 5. Februar 1992, 21:05     [/Lgr specified]
  1394.  
  1395. d1        Saturday, February 5, 1992
  1396.           samedi le 5 fevrier 1992      [/Lfr specified]
  1397.           Mittwoch, 5. Februar 1992     [/Lgr specified]
  1398.  
  1399. ddmn3yy   05Feb92
  1400.  
  1401. xxx       2CP  (...Dec 25, 1992)
  1402.           This format represents dates for the years 1990-2024 in 3
  1403.           characters of "extended hex" ("XX") notation.  For more on XX
  1404.           notation, see the discussion of the #2XX function.
  1405.  
  1406.           The first character is the XX representation of the number of
  1407.           years since 1990 (1990 = 0, 1991 = 1, etc.).  If you attempt to
  1408.           output a date outside of the 1990-2024 range in XXX format, Fdate
  1409.           will report an error (i.e. return "ERROR" and errorlevel of 1).
  1410.  
  1411.           The second and third characters contain the XX representation of
  1412.           the month-number and day-of-month-number, respectively.
  1413.  
  1414.           EXAMPLE: "1993 Feb  1"  is represented as  "321"
  1415.           EXAMPLE: "2000 Dec 25"  is represented as  "ACP".
  1416.  
  1417. -----------------------------------------------------------------------
  1418. NOTE that the following formats contain embedded spaces.  Consequently
  1419. they must be enclosed in double quotes. EXAMPLE: /O"mn zd, ccyy".
  1420. -----------------------------------------------------------------------
  1421. "zd mn ccyy"      5 February 1992
  1422. "zd mn, ccyy"     5 February, 1992
  1423. "zd. mn ccyy"     5. February 1992   [German-style date format]
  1424. "zd. mn3 ccyy"    5. Feb 1992        [German-style date format]
  1425. "mn3 dd ccyy"     Feb 05 1992
  1426. "mn3 dd, ccyy"    Feb 05, 1992
  1427. "mn zd, ccyy"     February 5, 1992
  1428.  
  1429.  
  1430.  
  1431. LEAP-YEAR FLAG OUTPUT FORMAT
  1432. ============================
  1433.  
  1434. LY              0     "1" if date occurs in a leapyear, otherwise "0".
  1435.  
  1436.                  365 + this number gives total number of days in the year.
  1437.                   28 + this number gives total number of days in February.
  1438.  
  1439.  
  1440.  
  1441.  
  1442. TIME OUTPUT FORMATS
  1443. ===================
  1444. See also: the section on the /T (parm /A time override) parameter.
  1445.  
  1446. t1            9:05 am
  1447.               9:05 pm
  1448.  
  1449. tdos          9:05:10:10a     format used in DOS's TIME command 
  1450.               9:05:10:10p
  1451.  
  1452. HH:MM        09:05      24-hour time, hours:minutes
  1453.              21:05
  1454. HHMM         0905
  1455.              2105
  1456.  
  1457. HH:MM:SS     21:05:30   24-hour time, hours:minutes:seconds
  1458. HHMMSS       210530
  1459.  
  1460.  
  1461. BUSINESS JULIAN DATE OUTPUT FORMATS
  1462. ===================================
  1463.  
  1464. These are formats for "business julian" dates: dates expressed as the
  1465. number of days from the beginning of the year, when January 1 is day 1.
  1466.  
  1467. EXAMPLES:
  1468.  
  1469.       DATE      BUSINESS JULIAN DATE
  1470.   -----------   --------------------
  1471.   Jan  5, 1993  93005
  1472.   Dec 31, 1993  93365  [Dec 31 is 365th day of year 1993]
  1473.   Dec 31, 1996  96366  [Dec 31 is 366th day, because 1996 is a leap year]
  1474.  
  1475.  
  1476. FORMAT        EXAMPLES      DISCUSSION
  1477. ------        ---------     -----------------------------
  1478.  
  1479. ccyyjjj       1992027       Jan 27, 1992
  1480.   yyjjj         92027       "Business Julian" date expressed as number
  1481.     jjj           027       of days since January 1 of the same year.
  1482.     zzj            27       Note leading zero suppression in "zzj".
  1483.  
  1484.  
  1485. ABSOLUTE DATE/TIME OUTPUT FORMATS
  1486. =================================
  1487. See also: the section on the /T (parm /A time override) parameter.
  1488.  
  1489.  
  1490. month#          23927      "Absolute month": date expressed as number of
  1491.                            months since the beginning of the calendar. 
  1492.                            Returns "1" for any date in January, 0001, "2"
  1493.                            for any date in February, 0001, etc.
  1494.  
  1495. day#           727198      "Absolute date": date expressed as number of
  1496.                            days since the beginning of the calendar. 
  1497.                            Returns "1" for January 1, 0001, "2" for
  1498.                            January 2, 0001, etc.
  1499.  
  1500. minute#         33088       "Absolute minutes": time expressed as number
  1501.                             of minutes  since midnight, January 1, 1990.
  1502.  
  1503. second#        633088       "Absolute seconds": time expressed as number
  1504.                             of seconds  since midnight, January 1, 1990.
  1505.  
  1506.  
  1507. Running FDATE with /O parameter for an "absolute time" produces a
  1508. number based on the current time of day and the date in the /A parm.
  1509.  
  1510. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1511.        FDATE /Ff /Atoday /Ominute#
  1512. it will produce the absolute minute for January 10, 1992 at 2 pm.
  1513.  
  1514. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1515.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#
  1516. it will produce the absolute minute for January 15, 1992 at 2 pm.
  1517.  
  1518.  
  1519. /T: TIME OVERRIDE PARAMETER
  1520. ===============================
  1521.  
  1522. You may override Fdate's use of the current time -- for the /A parameter
  1523. only -- by using the /T parameter.  The /T parameter specifies a time of
  1524. day in the 24-hour format hh:mm:ss (hours:minutes:seconds).  Leading zeros
  1525. in each of the three fields (hh, mm, ss) may be omitted.  The seconds field
  1526. may be omitted; if omitted, it defaults to "00".
  1527.  
  1528. Note that the /T parm overrides the time portion of the /A date, but it
  1529. does NOT override the time portion of the /B date.
  1530.  
  1531. If, on January 10, 1992 at 2 pm, you run FDATE this way:
  1532.        FDATE /Ff /A01-15-1992 /Imm-dd-ccyy  /Ominute#  /T5:12
  1533. it will produce the absolute minute for January 15, 1992 at 5:12 am.
  1534.  
  1535. The most frequent and important use of the /T parm is with the format
  1536. function (/Ff) to obtain the "absolute" minute of a specific date and time. 
  1537. Once we have the absolute minutes of two different date/times, we can
  1538. easily obtain the time between them (expressed in days, hours, and minutes)
  1539. by using Fdate's #dif, #idiv, and #mod functions.  (In the EXAMPLES
  1540. section, see the example that contains FORATIME.BAT.)
  1541.  
  1542. It is also possible to use /T in conjunction with the time compare function
  1543. (/Ftcomp).
  1544.  
  1545. @echo ON
  1546. cls
  1547. rem  Since both /A and /B default to the current date and time,
  1548. rem  and since /T parm overrides the time only for the /A parm ...
  1549.  
  1550. rem   ... during daytime hours, this will always return LT
  1551. Fdate /ftcomp /T00:00:00
  1552. rem   ... during daytime hours, this will always return GT
  1553. Fdate /ftcomp /T23:59:59
  1554.  
  1555.  
  1556. /J: JUSTIFYING OUTPUT
  1557. ==========================
  1558. Using the /J (justify) parameter it is possible to right, center, or left-
  1559. justify FDATE's output.  See the discussion of JUSTIFYING OUTPUT in the
  1560. section on string-handling functions.
  1561.  
  1562.  
  1563.  
  1564. HOW TO PUT FDATE OUTPUT INTO AN ENVIRONMENT VARIABLE
  1565. ====================================================
  1566.  
  1567.  
  1568. CALL A BATCH FILE
  1569. =================
  1570.  
  1571.   The most basic way to put FDATE's output into an environment variable,
  1572.   although not the most convenient, is to:
  1573.   *  use the /P (prefix string) feature to create a DOS "SET" statement,
  1574.   *  redirect the output to a batch file, and then
  1575.   *  CALL the batch file.  
  1576.  
  1577.   Since CALL first appeared in DOS 3.3, you will need DOS 3.3 or greater
  1578.   to use this technique.
  1579.  
  1580.        FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET FDATE=" >JUNKTEMP.BAT
  1581.        call JUNKTEMP.BAT
  1582.        del  JUNKTEMP.BAT
  1583.  
  1584.  
  1585.  
  1586. USE AN ENVIRONMENT-MANIPULATION UTILITY
  1587. =======================================
  1588.  
  1589.   There are shareware and public domain utilities that are written
  1590.   specifically to manipulate environment variables, and do that job very
  1591.   well.  FDATE's output can be put into an environment variable by piping
  1592.   it to one of these utilities.  When piping FDATE output to a utility,
  1593.   you can prevent the output from being ECHOed to the screen by
  1594.   redirecting the output to NUL.
  1595.  
  1596.   Of these utilities, I can especially recommend Bob Stephan's GET
  1597.   (because it is very inexpensive and very powerful and flexible) and PC
  1598.   Magazine's STRINGS (free to ZiffNet members).  See the EXAMPLES section
  1599.   for examples of how to use STRINGS and GET to put FDATE's output into an
  1600.   environment variable.
  1601.  
  1602.      As of March 14, 1994, the current version of GET is 2.6.  On
  1603.      CompuServe, use IBMFF to look for GET25.ZIP (which contains version
  1604.      2.5 and the full documentation file) and GET26u.ZIP (the version 2.6
  1605.      update of GET, which contains version 2.6 of GET, but not the full
  1606.      documentation).  Look in CIS:IBMSYS, Library 1, or for GET.ZIP in
  1607.      ZNT:UTILFORUM, lib 16.  GET is also available from the Public Software
  1608.      Library in Houston.
  1609.  
  1610.      As of February 14, 1992, the current version of STRINGS is 1.3. On
  1611.      CompuServe, look for STRING.ZIP in the PC Magazine Utilities Lib of
  1612.      ZNT:UTILFORUM.  STRHYP.ZIP contains good hypertext documentation on
  1613.      STRINGS.
  1614.  
  1615. FDATE'S /V PARAMETER
  1616. ====================
  1617.  
  1618.   Manipulating the environment is an incredibly tricky business.  There
  1619.   are questions of the local versus master environment, the version of DOS
  1620.   you are running, and the environment under which you are running (DOS,
  1621.   Windows, QuarterDeck, Carousel).  In order to keep FDATE focussed on
  1622.   date-related issues, versions of Fdate prior to 6.1 did not attempt to
  1623.   put output directly into an environment variable.  Instead, FDATE's
  1624.   output was written to standard output, that is, it was displayed on the
  1625.   screen. Output could then be redirected to a batch file, or piped to a
  1626.   utility (such as STRINGS or GET), that would put the output into an
  1627.   environment variable.
  1628.  
  1629.   Starting with version 6.1, Fdate supports a /V (environment variable)
  1630.   parameter.  A user can use /V to tell Fdate to put its output directly
  1631.   into an environment variable in the "parent" environment.
  1632.  
  1633.   NOTE that due to the complexities of manipulating the environment, there
  1634.   may be circumstances where /V doesn't work.  These include running FDATE
  1635.   when you have shelled out to DOS from another program, have put the
  1636.   command processor in upper memory (UMB) (see below), are running under
  1637.   Carousel, etc.  In such cases, you may be able to use one of the more
  1638.   basic techniques described above.  For a list of environments in which
  1639.   the /V option has been reported as NOT working, see the next section.
  1640.  
  1641.  
  1642.  
  1643.   /Vevar tells Fdate to put output into an environmental variable whose
  1644.   name is "evar".  For example:
  1645.  
  1646.                 Fdate /Ff /Vdate1
  1647.  
  1648.   will set the environment variable DATE1 to the current date.  If you
  1649.   type SET at the DOS prompt, you should see something like:
  1650.  
  1651.                 DATE1=Friday February 14, 1992
  1652.  
  1653.   If you specify /V without an evar name, the evar name defaults to FDATE.
  1654.  
  1655.      Example :       Fdate /Ff /V
  1656.      produces:       FDATE=Friday February 14, 1992
  1657.  
  1658.   If you do not use /V, Fdate output is written to standard output, i.e.
  1659.   to the screen.
  1660.  
  1661. /V WHEN RUNNING UNDER MICROSOFT WINDOWS
  1662. =======================================
  1663.  
  1664. Starting with FDATE version 8.4 -- thanks to a Turbo Pascal routine from
  1665. the Turbo Professional library (see below) provided by Kim Kokkonen of
  1666. TurboPower Software -- FDATE's /V parameter works even in a Windows DOS
  1667. box, assuming you have enough environment space available.
  1668.  
  1669. The problem is that when you shell out to a DOS box under Windows, the size
  1670. of the DOS environment is normally limited to the amount actually in use by
  1671. DOS at the time when you first started Windows (rounded up to multiples of
  1672. 16).  In short, when you shell out to DOS under Windows, you have little or
  1673. no free environment space left. 
  1674.  
  1675. The trick to giving yourself a decent amount of environment space in a
  1676. Windows DOS box, is to edit SYSTEM.INI and put the following line in the
  1677. [NonWindowsApp] section:
  1678.  
  1679.             [NonWindowsApp]
  1680.             CommandEnvSize=1024
  1681.  
  1682. This tip is from Brian Livingston's "Windows 3.1 Secrets", p. 225. 
  1683. According to Livingston, "This command allocates 1,024 bytes of
  1684. conventional memory to the environment space of each DOS session you start.
  1685. (You can choose any value you want, but it should probably be a multiple of
  1686. 16 bytes...)"
  1687.  
  1688. It's a good idea to be generous here, because the default prompt for a
  1689. Windows DOS box (the one with the highlighted bar across the top of the
  1690. screen) consumes a lot more environment space than the simple "$p$g" of the
  1691. conventional DOS prompt.
  1692.  
  1693. An alternative technique, if you're running Windows 3.0 or earlier, is
  1694. always to start Windows from a batch file that contains the following line,
  1695. executed BEFORE you start Windows:
  1696.  
  1697.    SET DUMMY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  1698.  
  1699. This will reserve a chunk of environment space that will be copied into the
  1700. environment in the Windows DOS box.  Then, as one of the first statements
  1701. in any batch file that you run under Windows, put
  1702.  
  1703.    SET DUMMY=
  1704.  
  1705. This will free up the environment space used by all those "X"s.  
  1706.  
  1707. For a good treatment of running DOS apps under Windows, including a
  1708. discussion of the environment, I recommend Brian Livingston's WINDOWS 3.1
  1709. SECRETS, chapter 7.
  1710.  
  1711.  
  1712. /V WHEN RUNNING UNDER WINDOWS NT
  1713. =======================================
  1714.  
  1715. Early in 1996, reports began trickling in of users having difficulty with
  1716. Fdate's /V feature (setting the value of an environment variable) when
  1717. running under Windows NT.  To make a long story short, Fdate's /V feature
  1718. doesn't work under Windows NT.  I am investigating possible solutions to
  1719. this problem, but cannot say when, or if, Fdate's /V feature will ever work
  1720. under NT.
  1721.  
  1722. This does not mean, however, that Fdate can't be used with NT.  What it
  1723. means is that, when running Fdate under NT, we have to fall back on a more
  1724. basic method of setting an environment variable.  This involves creating a
  1725. temporary batch file that sets the variable, then running and deleting the
  1726. batch file.  It's primitive, but it works.
  1727.  
  1728. This technique is described elsewhere in this documentation, but I will
  1729. repeat it here for convenience's sake.
  1730.  
  1731. CALL A BATCH FILE
  1732. =================
  1733.  
  1734. The most basic way to put FDATE's output into an environment variable is
  1735. to:
  1736.  
  1737.   *  use the /P (prefix string) feature to create a DOS "SET" statement and
  1738.   *  redirect the output to a temporary batch file, and then
  1739.   *  CALL the batch file, and then  
  1740.   *  delete the batch file (clean up after the operation). 
  1741.  
  1742. EXAMPLE:
  1743.  
  1744.        FDATE /Ff /At /Occyymmdd /P"@SET FDATE=" >JUNKTEMP.BAT
  1745.        call JUNKTEMP.BAT
  1746.        del  JUNKTEMP.BAT
  1747.  
  1748. In this example, the result will be that the FDATE environment variable is
  1749. set to today's date, in ccyymmdd format.
  1750.  
  1751. Turbo Professional: "Highly Recommended"
  1752.  
  1753.   Thanks to a Turbo Pascal routine from the Turbo Professional library
  1754.   (provided by Kim Kokkonen of TurboPower Software)  FDATE's /V parameter
  1755.   works even in a Windows DOS box.
  1756.  
  1757.   If you do serious Turbo Pascal programming, you should have Turbo
  1758.   Professional or Object Professional library.  Turbo Professional is a
  1759.   library of about 600 routines to do all sorts of useful stuff in Turbo
  1760.   Pascal programs, including:
  1761.  
  1762.     CRT unit emulation, with many added features 
  1763.     Popup windows, virtual screens, and pulldown menu systems.
  1764.     Full screen data entry with formatting and data validation.
  1765.     Complete mouse support, keyboard macros, runtime error recovery.
  1766.     A context sensitive popup help unit.
  1767.     Units for picking from lists of items, including filenames.
  1768.     Easy and reliable ways to make your program memory resident.
  1769.     Interrupt service routine handlers, extended & expanded memory access.
  1770.     BCD arithmetic, including transcendental functions & the Form routine
  1771.     Sorting and searching.
  1772.     Extensive string manipulation & strings longer than 255 characters.
  1773.     Arrays larger than 64K (in RAM, EMS, or paged to disk)
  1774.  
  1775. For more information, call TurboPower at 1-800-333-4160 (9-5 Mountain
  1776. time), send CompuServe mail to 76004,2611, or visit the CompuServe
  1777. TurboPower forum in PCVENB section 6.
  1778.  
  1779. /V WHEN USING 4DOS, NDOS, AND UMB
  1780. =================================
  1781.     --------------------------------------------------------------
  1782.     I have received the following report from Aran Spence about
  1783.     circumstances in which FDATE /V will not set a variable
  1784.     in the master environment.  This report leads me to believe
  1785.     that FDATE /V may also fail to work with MS-DOS if you put
  1786.     the command processor or the environment in Upper Memory.
  1787.                     Note, however, that this behavior has not been tested
  1788.                     with FDATE 8.4's new environment-handling routines.
  1789.     --------------------------------------------------------------
  1790. Steve,
  1791.  
  1792. There are options with 4DOS and NDOS to load the environment and part
  1793. of the command processor into upper memory blocks.  When one of these
  1794. options is used, FDATE /V can't find the environment and produces the
  1795. message:
  1796.  
  1797.    ERROR
  1798.    @echo ERROR: Master environment not found
  1799.    @pause
  1800.  
  1801. If you have a 4DOS.INI file, it has to contain these lines for FDATE /V
  1802. to work:
  1803.  
  1804.    UMBEnvironment = No
  1805.    UMBLoad = No
  1806.  
  1807. If you have NDOS, the SHELL statement in CONFIG.SYS cannot contain
  1808. any reference to UMB loading via /U (which puts NDOS.COM in UMB), nor
  1809. can it contain a statement of the form:
  1810.                 /E:xxxU
  1811. (which puts xxx bytes of the environment in UMB via the "U" parameter).
  1812.  
  1813. Also, NSTART.BTM or 4START.BTM cannot contain
  1814.          SET NDSHELL=/e+xxxU /U
  1815. in which both U's represent UMB loading of the command processor and the
  1816. environment during secondary shells.
  1817.  
  1818. FDATE'S ERROR HANDLING
  1819. ======================
  1820.  
  1821.    If FDATE detects an error:
  1822.  
  1823.      (1) it will return an errorlevel of 1 (rather than 0), and
  1824.      (2) its output will be 3 lines:
  1825.        * the word ERROR
  1826.        * a DOS batch-file ECHO statement that displays an error message
  1827.        * a DOS batch-file PAUSE statement
  1828.  
  1829.    If Fdate output is displayed directly, or redirected to NUL,
  1830.    you can detect an error by testing the errorlevel for a value of 1.
  1831.  
  1832.    If Fdate output is piped to an environment manipulation utility such
  1833.    as STRINGS or GET, the environment variable will be set to ERROR.
  1834.    Errorlevel will be set by STRINGS/GET, and will probably be 0.
  1835.    In such a case, the only way to detect an error is to test the
  1836.    environment variable for the value ERROR.
  1837.  
  1838.    If FDATE output is redirected to a batch file, which is then
  1839.    CALLed to set an environment variable, the batch file will:
  1840.      * set the environment variable to ERROR,
  1841.      * ECHO the error message, and
  1842.      * pause.
  1843.    You can detect an error by testing errorlevel for the value 1
  1844.    either before or after you CALL the batch file, or 
  1845.    by testing the environment variable for the
  1846.    value ERROR, AFTER you have CALLed the batch file.
  1847.  
  1848. ----------------------------------------------------------------------
  1849.  
  1850.  EXAMPLE:
  1851.    rem use FDATE to check validity of year in parm %1
  1852.    Fdate /Fv /Imm-dd-ccyy /ATT-TT-%1 > nul
  1853.    if errorlevel 1 echo Year parm [%1] is not valid.
  1854.    if errorlevel 1 goto endit
  1855.  
  1856.  EXAMPLE:
  1857.    rem use GET with FDATE, to put FDATE output into %year%
  1858.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy | GET ZE /V%year% >nul
  1859.    if (%year%)==(ERROR) echo Year parm [%1] is not valid.
  1860.    if (%year%)==(ERROR) goto endit
  1861.  
  1862.  EXAMPLE:
  1863.    rem use a batch file with FDATE, to put FDATE output into %year%
  1864.    Fdate /Ff /Imm-dd-ccyy /ATT-TT-%1 /Occyy /P"@set year=">junktemp.bat
  1865.    call junktemp.bat
  1866.    del  junktemp.bat
  1867.    if errorlevel 1 echo Year parm [%1] is not valid.
  1868.    if errorlevel 1 goto endit
  1869.  
  1870. EXAMPLES OF HOW TO USE FDATE
  1871. ============================
  1872.  
  1873. :01 Display Fdate output on screen
  1874. :==================================================================
  1875. FDATE /Ff /At /Od1 /P"Today is "
  1876.  
  1877.  
  1878. :02 Redirect FDATE output to a file
  1879. :==================================================================
  1880. FDATE /Ff /At /Od1 /P"Today is " >FDATE.OUT
  1881.  
  1882.  
  1883. :03 Put FDATE output in an environment variable using a batch file
  1884. :==================================================================
  1885. FDATE /Ff /Atoday /O"mn zd, ccyy" /P"@SET DATE1=" >JUNKTEMP.BAT
  1886. call JUNKTEMP.BAT
  1887. del  JUNKTEMP.BAT
  1888.  
  1889.  
  1890. :04 Put FDATE output in an environment variable using /V parm
  1891. :==================================================================
  1892. FDATE /Ff /Atoday /O"mn zd, ccyy" /Vdate1
  1893.  
  1894.  
  1895. :05 Put FDATE output in an environment variable using STRINGS
  1896. :==================================================================
  1897. FDATE /Ff /Atoday /O"mn zd, ccyy" |STRINGS date1= ASK >NUL
  1898.  
  1899.  
  1900. :06 Put FDATE output in an environment variable using GET
  1901. :==================================================================
  1902. FDATE /Ff /Atoday /O"mn zd, ccyy" |GET ZE /Vdate1 >NUL
  1903.  
  1904.  
  1905. :07 Get user input
  1906. :==================================================================
  1907. @echo off
  1908. cls
  1909. echo Enter a date in mm-dd-ccyy format for validation
  1910.  
  1911. :: get user input
  1912. fdate /fget /vUserDate1
  1913.  
  1914. :: validate user input using /Fv (validate function)
  1915. fdate /fv /A%UserDate1% >nul
  1916. if errorlevel 1 echo Invalid date: %UserDate1%
  1917. if errorlevel 1 goto endit
  1918.  
  1919. :: put your batch file processing here ...
  1920. echo Processing date: %UserDate1%
  1921.  
  1922. :endit
  1923. :: cleanup
  1924. set UserDate1=
  1925.  
  1926.  
  1927. :08 Get a user menu selection
  1928. :==================================================================
  1929. @echo off
  1930. :start
  1931. cls
  1932. echo ===========================================================
  1933. echo             MAKE A MENU SELECTION
  1934. echo ===========================================================
  1935. echo   A   DIR *.*
  1936. echo   B   DIR *.BAT
  1937. echo.
  1938. echo Press ESC to exit
  1939. echo.
  1940. echo ===========================================================
  1941. FDATE /FgetK /Q"Press letter of your choice> " /KABx /V
  1942.  
  1943. if (%FDATE%)==(A) goto Choice_%FDATE%
  1944. if (%FDATE%)==(B) goto Choice_%FDATE%
  1945. if (%FDATE%)==(x) goto endit
  1946. echo Program logic error.   Invalid choice [%FDATE%]
  1947. pause
  1948. goto Start
  1949.  
  1950. :CHOICE_A
  1951.  cls
  1952.  echo Processing choice %FDATE% ...
  1953.  DIR *.* /W /P
  1954.  pause
  1955.  goto Start
  1956.  
  1957. :CHOICE_B
  1958.  echo Processing choice %FDATE% ...
  1959.  DIR *.BAT /W /P
  1960.  pause
  1961.  goto Start
  1962.  
  1963. :endit
  1964. set choice=
  1965. cls
  1966.  
  1967.  
  1968. :10 Change a date from one format into another
  1969. :==================================================================
  1970. :: change date from mm-dd-yy format to ccyymmdd format
  1971. FDATE /Ff /Imm-dd-yy /A05-08-92 /Occyymmdd
  1972.  
  1973.  
  1974.  
  1975. :11 Find the difference in days between two dates
  1976. :==================================================================
  1977. FDATE /Fdif /Imm-dd-ccyy /A%date1% /B%date2% /vdiff
  1978. echo The difference is %diff% days.
  1979.  
  1980.  
  1981. :12 Find the elapsed days/hours/minutes between two date/times.
  1982. :===================================================================
  1983. This batch file was developed in cooperation with Walter Ledge, a sysop for
  1984. CompuServe's CRFORUM.  In addition to being a good example of how to use
  1985. Fdate's /T parm and "#idiv" function, it should be useful for other
  1986. CompuServe sysops who need to submit the same reports that Walt does. 
  1987. Here's Walt's message that started the whole thing.
  1988.  
  1989.   As an assistant sysop on the CRFORUM, I have to submit reports to CIS on
  1990.   the number of messages that are posted on our forum in terms of time per
  1991.   1,000 messages -- i.e., say, I know that 1,000 messages were posted
  1992.   between the hours of 17:05 on July 5 and 3:03 on July 7.  I need to know
  1993.   how many hours and minutes it took for those 1000 messages to be posted. 
  1994.   So I would like some way to use FDATE to calculate the difference
  1995.   between those two times (which, of course, include the dates).
  1996.  
  1997. FORATIM2.BAT is an improvement of the original FORATIME.BAT batch file. 
  1998. FORATIM2.BAT uses the /Fget function, which first appeared in Fdate 8.3, to
  1999. get user input from the terminal, rather than requiring all parameters to
  2000. be entered at the command line as FORATIME.BAT did. 
  2001.  
  2002. @echo off
  2003. cls
  2004. :: ------------------------------------------------------
  2005. :: FORATIM2.BAT batch file
  2006. ::
  2007. :: FUNCTION
  2008. ::    Calculate the elapsed time (in days and minutes)
  2009. ::    between some "begin" date/time and some "end" date/time
  2010. ::
  2011. :: ------------------------------------------------------
  2012. ECHO --------------------------------------------------------------
  2013. ECHO     Calculate elapsed time between two date/times
  2014. ECHO --------------------------------------------------------------
  2015.  
  2016. :BegDate
  2017. Fdate /Fget /VBEGdate /Q"Enter BEGIN DATE (mm-dd-ccyy): "
  2018. if (%BegDate%)==() goto Cleanup
  2019.  
  2020. :BegTime
  2021. Fdate /Fget /VBEGtime /Q"Enter BEGIN TIME (hh:mm).....: "
  2022. if (%BegTime%)==() goto Cleanup
  2023.  
  2024. :: validate date & time
  2025. fdate /fv /A%BEGdate% /T%BEGtime% >nul
  2026. if errorlevel 1 echo Invalid date/time
  2027. if errorlevel 1 goto BegDate
  2028.  
  2029. :: get absolute minute of start date/time.
  2030. fdate /ff /ominute# /A%BEGdate% /T%BEGtime% /VABStime1
  2031. if errorlevel 1 goto BegTime
  2032. fdate /ff /ofull    /A%BEGdate% /T%BEGtime% /Vfull1
  2033. ::
  2034. echo.
  2035. :EndDate
  2036. Fdate /Fget /VENDdate /Q"Enter END.. DATE (mm-dd-ccyy): "
  2037. if (%EndDate%)==() goto Cleanup
  2038.  
  2039. :EndTime
  2040. Fdate /Fget /VENDtime /Q"Enter END.. TIME (hh:mm).....: "
  2041. if (%EndTime%)==() goto Cleanup
  2042.  
  2043. :: validate date & time
  2044. fdate /fv /A%ENDdate% /T%ENDtime% >nul
  2045. if errorlevel 1 echo Invalid date/time
  2046. if errorlevel 1 goto EndDate
  2047.  
  2048. :: get absolute minute of end date/time.
  2049. fdate /ff /ominute# /A%ENDdate% /T%ENDtime% /VABStime2
  2050. if errorlevel 1 goto EndTime
  2051. fdate /ff /ofull    /A%ENDdate% /T%ENDtime% /Vfull2
  2052.  
  2053. echo.
  2054. ECHO Calculating elapsed time...
  2055. :: calculate the difference between ABStime1 and ABStime2
  2056. fdate /f#dif  /A%ABStime1% /B%ABStime2% /VMinutes
  2057.  
  2058. :: calculate the number of hours in it took
  2059. fdate /f#Idiv  /A%minutes% /B60  /VHours
  2060.  
  2061. :: calculate the number of extra minutes it took
  2062. fdate /f#mod   /A%minutes% /B60  /VMins
  2063.  
  2064. echo.
  2065. echo   Between %full1%
  2066. echo       and %full2%
  2067. echo.
  2068. echo   Elapsed time was:
  2069. echo           %hours% hours and %mins% minutes
  2070.  
  2071. fdate /f#Idiv /A%minutes% /B1440 /Vday1
  2072. fdate /f#mod  /A%minutes% /B1440 /Vmin1
  2073. fdate /f#Idiv /A%min1%    /B60   /Vhour1
  2074. fdate /f#mod  /A%min1%    /B60   /Vmin2
  2075. echo   or
  2076. echo         %day1% day(s) %hour1% hour(s) and %min2% minute(s).
  2077. echo.
  2078. echo.
  2079. ::
  2080. :cleanup
  2081. set ENDdate=
  2082. set BEGdate=
  2083. set BEGtime=
  2084. set ENDtime=
  2085. set full1=
  2086. set full2=
  2087. set minutes=
  2088. set ABStime1=
  2089. set ABStime2=
  2090. set day1=
  2091. set hour1=
  2092. set min1=
  2093. set min2=
  2094. set mins=
  2095. set hours=
  2096. :endit
  2097. :13 Find the elapsed years/months/days between two dates.
  2098. :===================================================================
  2099. @echo off
  2100. :: illustrate Fdate's Month# output format
  2101. cls
  2102. echo --------------------------------------------------------------
  2103. echo    YMD_DIF.BAT Calculate elapsed time between two dates
  2104. echo --------------------------------------------------------------
  2105.  
  2106. :: --------------------------------------------------------------
  2107. :D1
  2108. Fdate /Fget /VD1 /Q"Enter date #1 (mm-dd-ccyy), or ENTER to quit: "
  2109. if (%D1%)==() goto Cleanup
  2110.  
  2111. :: validate date
  2112. Fdate /Fv /A%D1%       >nul
  2113. if errorlevel 1 echo Invalid date
  2114. if errorlevel 1 goto D1
  2115.  
  2116. :: translate date into various formats, including absolute month
  2117. Fdate /Ff /oMonth# /A%D1% /VAbsMonth1
  2118. Fdate /Ff /oday#   /A%D1% /VAbsDay1
  2119. Fdate /Ff /A%D1%   /VFull1
  2120. Fdate /Ff /odd     /A%D1% /VDd1
  2121.  
  2122. :: --------------------------------------------------------------
  2123. :D2
  2124. Fdate /Fget /VD2 /Q"Enter date #2 (mm-dd-ccyy), or ENTER to quit: "
  2125. echo.
  2126. if (%D2%)==() goto Cleanup
  2127.  
  2128. :: validate date
  2129. Fdate /Fv /A%D2% >nul
  2130. if errorlevel 1 echo Invalid date
  2131. if errorlevel 1 goto D2
  2132.  
  2133. :: translate date
  2134. Fdate /Ff /oMonth# /A%D2% /VAbsMonth2
  2135. Fdate /Ff /oday#   /A%D2% /VAbsDay2
  2136. Fdate /Ff /A%D2%   /VFull2
  2137. Fdate /Ff /odd     /A%D2% /VDd2
  2138.  
  2139. :: --------------------------------------------------------------
  2140. :: verify that D2 is later than D1
  2141. Fdate /Fcomp /A%D2% /B%D1% /v
  2142. if (%Fdate%)==(GT) goto EndIf1
  2143.    echo     D2 must be later than D1.        Please try again.
  2144.    echo.
  2145.    goto D1
  2146. :EndIf1
  2147.  
  2148. :: verify that D2 is in a later month than D1
  2149. Fdate /F#comp /A%AbsMonth2% /B%Absmonth1% /v
  2150. if (%Fdate%)==(GT) goto EndIf2
  2151.    :: they are in the same month
  2152.    Fdate /Fdif /A%D1% /B%D2% /P"Difference is " /S" days."
  2153.    echo.
  2154.    goto Cleanup
  2155. :EndIf2
  2156.  
  2157. :: --------------------------------------------------------------
  2158. :: get difference in months
  2159. Fdate /F#dif /A%AbsMonth2% /B%Absmonth1% /vMonthsDif
  2160.  
  2161. :: compare days of month
  2162. Fdate /F#comp /A%Dd2% /B%Dd1% /v
  2163. if not (%Fdate%)==(LT) goto EndIf3
  2164.    :: Dd2 is less than Dd1 ... subtract 1 from (add -1 to) MonthsDif
  2165.    Fdate /F#add  /A%MonthsDif% /B-1 /VMonthsDif
  2166. :EndIf3
  2167.  
  2168.  
  2169. :: do month arithmetic, to get a date (D3) that is
  2170. :: less than 1 month prior to D2
  2171. Fdate /Fm /A%D1% /N%MonthsDif% /Omm-dd-ccyy /VD3
  2172.  
  2173. :: find difference in days between D3 & D2
  2174. Fdate /Fdif /A%D3% /B%D2% /Vdaysdif
  2175.  
  2176. :: --------------------------------------------------------------
  2177. echo Between %Full1% & %Full2% ...
  2178. echo                 %MonthsDif% month(s) %DaysDif% day(s)
  2179.  
  2180. :: calculate the number of years, by dividing MonthsDif by 12
  2181. Fdate /F#Idiv  /A%Monthsdif% /B12  /VYearsDif
  2182.  
  2183. :: calculate the number of extra months
  2184. Fdate /F#mod   /A%MonthsDif% /B12  /VMonthsDif
  2185.  
  2186. echo  or   %YearsDif% year(s) %MonthsDif% month(s) %DaysDif% day(s)
  2187.  
  2188. :: --------------------------------------------------------------
  2189. :cleanup
  2190. echo.
  2191. echo.
  2192. set D1=
  2193. set D2=
  2194. set D3=
  2195. set AbsMonth1=
  2196. set AbsMonth2=
  2197. set AbsDay1=
  2198. set AbsDay2=
  2199. set Full1=
  2200. set Full2=
  2201. set Dd1=
  2202. set Dd2=
  2203. set YearsDif=
  2204. set MonthsDif=
  2205. set DaysDif=
  2206. set Fdate=
  2207. :endit
  2208.  
  2209.  
  2210. :14 Determine how long it took a program to run
  2211. :==================================================================
  2212.  
  2213. @echo off
  2214. cls
  2215. ECHO ─────────────────────────────────────────────────────────────────────
  2216. ECHO       DETERMINE HOW LONG IT TOOK A PROGRAM TO RUN
  2217. ECHO           The demo will run for 1 - 60 seconds.
  2218. ECHO ──────────────────────────────────────────────────────────────────────
  2219. PAUSE
  2220. cls
  2221. :: Get the time (in julian seconds) that the program began running
  2222. set PgmName=DemoFake_Pgm
  2223. FDATE /Ff /Osecond# /VBegS
  2224. FDATE /Ff /Ohh:mm:ss /P"%PgmName% execution begins at "
  2225.  
  2226. :: ───────── DEMO BEGIN ──────────────────────────────────────────
  2227. :: For purposes of this demo, we simulate execution of a
  2228. :: program by looping until the minute changes.  In your real
  2229. :: batch file, you would put your program statements here.
  2230. :: ───────────────────────────────────────────────────────────────
  2231. FDATE /Ff /Ohhmm /vBegM
  2232. :BegLoop
  2233.    rem  Since this is a demo, give the folks something to watch
  2234.    FDATE /Ff    /Osecond# /vSeconds
  2235.    FDATE /F#dif /A%Seconds% /B%BegS% /P".... elapsed time: " /S" seconds."
  2236.    FDATE /Ff  /Ohhmm     /vNowM
  2237. if (%NowM%)==(%BegM%) goto BegLoop
  2238. set BegM=
  2239. set NowM=
  2240. :: ───────── DEMO END   ──────────────────────────────────────────
  2241.  
  2242. :: Get the time (in julian seconds) that the program finished
  2243. FDATE /Ff  /Osecond# /vEndS
  2244. :: tell the user the time that the program finished
  2245. FDATE /Ff  /Ohh:mm:ss /P"%PgmName% execution ends at "
  2246.  
  2247. :: calculate run time (difference between start time and end time)
  2248. FDATE /F#dif /A%EndS% /B%BegS% /vSeconds
  2249. :: convert  seconds to  minutes + seconds  format
  2250. FDATE /F#idiv /A%Seconds% /B60 /vMinutes
  2251. FDATE /F#mod  /A%Seconds% /B60 /vMinSecs
  2252.  
  2253. :: tell the user how long the program took to run
  2254. echo Runtime: %Seconds% seconds (%Minutes% minutes %MinSecs% seconds)
  2255. :: cleanup            
  2256. set PgmName=
  2257. set BegS=
  2258. set EndS=
  2259. set Seconds=
  2260. set Minutes=
  2261. set MinSecs=
  2262.  
  2263. :15 Find years when a given date fell on a given day of the week
  2264. :==================================================================
  2265. [WHATDAY.BAT  This program has virtually no data validation, but if you are
  2266. careful to enter valid input data, it does the job.] 
  2267.  
  2268.  @echo off
  2269.  :: ----------------------------------------------------------------
  2270.  :: This program calculates the years (within a specified range) that a
  2271.  :: certain day of a certain month fell on a certain day of the week.
  2272.  ::
  2273.  :: Note that we calculate and test both the day of the week and the
  2274.  :: month.  This is because, for example, "February 29" of
  2275.  :: a non-leapyear (an invalid date)
  2276.  :: will be converted to the valid date of March 1.
  2277.  :: So we want to be sure that in a given year, February 29 not only
  2278.  :: occurred on the weekday in question, but also actually
  2279.  :: occurred in February.
  2280.  :: ----------------------------------------------------------------
  2281.  cls
  2282.  echo This program calculates the years (within a specified range) that a
  2283.  echo certain day of a certain month fell on a certain day of the week.
  2284.  echo.
  2285.  echo Please enter the day of the week that you want to search for.
  2286.  echo   1 = Sunday
  2287.  echo   2 = Monday
  2288.  echo   3 = Tuesday
  2289.  echo   4 = Wednesday
  2290.  echo   5 = Thursday
  2291.  echo   6 = Friday
  2292.  echo   7 = Saturday
  2293.  echo.
  2294.  fdate /fgetk /K1234567x /Q"Please press a number, or ESC to exit > " /vdow
  2295.  if (%Dow%)==(x) goto endit
  2296.  if (%Dow%)==(1) set DowName=Sunday
  2297.  if (%Dow%)==(2) set DowName=Monday
  2298.  if (%Dow%)==(3) set DowName=Tuesday
  2299.  if (%Dow%)==(4) set DowName=Wednesday
  2300.  if (%Dow%)==(5) set DowName=Thursday
  2301.  if (%Dow%)==(6) set DowName=Friday
  2302.  if (%Dow%)==(7) set DowName=Saturday
  2303.  echo You chose day of the week: %dowName%
  2304.  pause
  2305.  
  2306.  fdate /fget /Q"Please enter first year in year range > " /vBegYr
  2307.  fdate /fget /Q"Please enter last_ year in year range > " /vEndYr
  2308.  fdate /fget /Q"Please enter month number (1-12) > " /vMonNum
  2309.  fdate /fget /Q"Please enter day__ number (1-31) > " /vDayNum
  2310.  
  2311.  set Yr=%BegYr%
  2312.  fdate /fsubstr /a-2 /q00%MonNum% /vMonNum
  2313.  
  2314.  rem >whatday.txt
  2315.  cls
  2316.  echo Looking for %MonNum%/%DayNum% on %DowName%
  2317.  echo between %BegYr% and %EndYr%
  2318.  echo ----------------------------------------------
  2319.  echo Looking for %MonNum%/%DayNum% on %DowName% >>whatday.txt
  2320.  echo between %BegYr% and %EndYr% >>whatday.txt
  2321.  echo ---------------------------------------------- >>whatday.txt
  2322.  
  2323.  :LoopTop
  2324.    fdate /fsubstr /a-4 /q0000%yr% /vyr
  2325.    echo Testing %yr%
  2326.    fdate /ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /v
  2327.    fdate /ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /odow# /vdow#
  2328.    fdate /ff /Idd-mm-ccyy /A%DayNum%-%MonNum%-%Yr% /omm   /vmm
  2329.  
  2330.    if (%Dow#%)==(%Dow%) if (%MonNum%)==(%mm%) echo %fdate%
  2331.    if (%Dow#%)==(%Dow%) if (%MonNum%)==(%mm%) echo %fdate% >>Whatday.txt
  2332.  
  2333.    fdate /f#add  /A%yr% /B1 /vYr
  2334.    fdate /f#comp /A%yr% /B%EndYr% /v
  2335.    if (%fdate%)==(GT) goto LoopEnd
  2336.    goto LoopTop
  2337.  :LoopEnd
  2338.  
  2339.  cls
  2340.  type whatday.txt
  2341.  echo.
  2342.  echo This data has been written to file: Whatday.txt
  2343.  echo.
  2344.  :endit
  2345.  set Yr=
  2346.  set BegYr=
  2347.  set EndYr=
  2348.  set mm=
  2349.  set Dow=
  2350.  set Dow#=
  2351.  set DowName=
  2352.  set fdate=
  2353.  set MonNum=
  2354.  set DayNum=
  2355.  
  2356. :16 Find calendar date corresponding to a "business Julian" date
  2357. :==================================================================
  2358. rem business julian date is 1992:045.  Note input format CCYYjjj
  2359. FDATE /Ff /A1992045  /Iccyyjjj  /Od1
  2360.  
  2361. rem You don't need to left-zero-fill the day
  2362. FDATE /Ff /A199245  /Iccyyjjj  /Od1
  2363.  
  2364. rem You can assume the century, if you specify the YYjjj input format
  2365. FDATE /Ff /A9245  /Iyyjjj  /Od1
  2366.  
  2367. :17 Set your PC's date to a business julian date
  2368. :==================================================================
  2369. @echo off
  2370. goto enddoc
  2371. ---------------------------------------------------------------------
  2372. This batch file was created by Aran Spence [CIS: 70162,3044].  Its
  2373. function is to emulate the DOS DATE command, but allow the user to set
  2374. the date using a business julian date format (yyjjj) instead of
  2375. mm-dd-yy.
  2376.  
  2377. Note the format is YYjjj. This is the BUSINESS julian date: a date
  2378. expressed as the number of days from the beginning of the year,
  2379. when January 1 is day 1.
  2380.  
  2381.            date      BUSINESS julian date
  2382.        -----------   --------------------
  2383.        Jan 5, 1992       92005
  2384.        Jan 5, 1993       93005
  2385.        Dec 31, 1993      93365  [Dec 31 is 365th day of year 1993]
  2386.  
  2387. As Aran originally wrote it, the user-prompt was virtually identical to
  2388. that of the DATE command.  I have modified his original version, so it
  2389. now looks less like the DATE command but displays a bit more
  2390. information, and so it can operate from the command line.
  2391.  
  2392. If the user enters a business julian date as a command-line
  2393. parameter, JDATE resets the date to that julian date.
  2394.              EXAMPLE:  JDATE 92005
  2395. If there is no input parameter, /fget is used to prompt the user for a
  2396. date.
  2397.  
  2398. Note that the user must enter both of the year digits (yy),
  2399. but may enter an abbreviated set of day digits (jjj).  That is,
  2400. for julian day 92005, the user is permitted to enter 925.
  2401.  
  2402. One handy use for JDATE is simply to find out what the current
  2403. business julian date is.
  2404. ---------------------------------------------------------------------
  2405. :enddoc
  2406.  
  2407. SET NewJD=%1
  2408. if not (%NewJD%)==() goto GotDate
  2409.  
  2410. :ShowDate
  2411. Fdate /Ff /Od1    /P"Current Gregorian date: "
  2412. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  2413.  
  2414. :GetDate
  2415. GET S "Enter new date (yyddd): " /VNewJD /L
  2416. if (%NewJD%)==() goto endit
  2417.  
  2418. :GotDate
  2419. Fdate /Ff /A%NewJD% /Omm-dd-yy /Iyyjjj /VNewGD
  2420. if errorlevel 1 echo Invalid date "%NewJD%"
  2421. if errorlevel 1 goto GetDate
  2422.  
  2423. ::   reset the date
  2424. DATE %NewGD%
  2425.  
  2426. echo SYSTEM DATE HAS BEEN RESET
  2427. Fdate /Ff /Od1    /P"Current Gregorian date: "
  2428. Fdate /Ff /Oyyjjj /P"'Business Julian' date: "
  2429.  
  2430. :endit
  2431. SET NewJD=
  2432. SET NewGD=
  2433. echo.
  2434.  
  2435. :18 Determine if parm %1 contains a valid date
  2436. :==================================================================
  2437. COMMENT
  2438.   Note that we throw away the FDATE output by redirecting it to NUL.  All
  2439.   we really want here is the errorlevel, which tells us whether or not the
  2440.   string in %1 is a valid year.
  2441.  
  2442. Fdate /Fv /Imm-dd-ccyy /A%1  >nul
  2443. if errorlevel 1 echo Parm 1 was not a valid date: %1
  2444. if errorlevel 1 goto endit
  2445.  
  2446. ::
  2447. :: Put the body of your batch file here.
  2448. ::
  2449.  
  2450. :endit
  2451.  
  2452.  
  2453.  
  2454. :19 "Roll your own" date format 
  2455. :==================================================================
  2456. @echo of
  2457. cls
  2458. :: EXAMPLE A: create a date in the format of the DOS "date" command
  2459. :: format, followed by the DOS "time" command format
  2460.  
  2461. :: get the three-character day-of-week name
  2462. Fdate /Ff /Odow3 /Vx
  2463.  
  2464. :: add mm-dd-ccyy to it
  2465. Fdate /Ff /Omm-dd-ccyy /p"%x% " /Vx
  2466.  
  2467. :: add the DOS "time" format (new output format in Fdate 8.6)
  2468. Fdate /Ff /Otdos       /p"%x% " /Vx
  2469. echo Date/time = %x%
  2470.  
  2471. :: EXAMPLE B: create a date in custom-made format: yymn3dd
  2472. Fdate /Ff /Oyy          /Vx
  2473. Fdate /Ff /Omn3 /P"%x%" /Vx
  2474. Fdate /Ff /Odd  /P"%x%" /Vx
  2475. echo Today is %x%
  2476.  
  2477. :: EXAMPLE C: create a date with day and month date-parts right justified
  2478. ::            and padded with spaces, such as " 1- 1-1995" for Jan 1, 1995
  2479. fdate /ff /ozd   /j"R 2" /vzd
  2480. fdate /ff /ozm   /j"R 2" /vzm
  2481. fdate /ff /occyy /p"%zd%-%zm%-"  /v
  2482. echo Today is [%fdate%]
  2483.  
  2484. :20 Find the 4th Thursday in November (Thanksgiving)
  2485. :==================================================================
  2486. Fdate /Fw /D5 /N4 /A11-01-%year% /Imm-dd-ccyy /Od1 /P"Thanksgiving: "
  2487.  
  2488.  
  2489. :22 On a date, show what anniversary it is for some event
  2490. :==================================================================
  2491. See HOLIDAYS.BAT demo batch file
  2492.  
  2493.  
  2494. :23 Show a list of holidays in a given year
  2495. :==================================================================
  2496. See HOLIDAYS.BAT demo batch file
  2497.  
  2498.  
  2499. :24 Show a list of Federal holidays in a given year
  2500. :==================================================================
  2501. See HOLIFEDS.BAT demo batch file
  2502.  
  2503. :25 Determine if a year is valid, and evenly divisible by 4
  2504. :==================================================================
  2505.  
  2506. @echo off
  2507. cls
  2508. echo FUNCTION: Accept a year parm (CCYY) as parameter 1.  Determine if
  2509. echo the year is an election or inauguration year in the United States.
  2510. echo ===================================================================
  2511.  
  2512. rem verify %1 is a valid year
  2513. Fdate /Fv /Imm-dd-ccyy /A01-01-%1 >nul
  2514. if errorlevel 1 echo Year parm [%1] is not valid.
  2515. if errorlevel 1 goto endit
  2516.  
  2517. Fdate /Ff /Imm-dd-ccyy /A01-01-%1 /p"@set year=">junktemp.bat
  2518. call junktemp.bat
  2519.  
  2520. Fdate /F#mod /A%1 /B4 /p"@set mod=">junktemp.bat
  2521. call junktemp.bat
  2522. if (%mod%)==(0) echo %1 is an American presidential election year.
  2523. if (%mod%)==(1) echo %1 is an American presidential inauguration year.
  2524. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an election year.
  2525. for %%v in (2 3) do if (%mod%)==(%%v) echo %1 is not an inauguration year.
  2526.  
  2527. set mod=
  2528. :endit
  2529. if exist junktemp.bat del  junktemp.bat
  2530.  
  2531.  
  2532.  
  2533.  
  2534. :30 Compare a file's date to today's date
  2535. :==================================================================
  2536. rem Compare today's date to the date on the filename in %1
  2537. Fdate /Fcomp /At /If /B%1 /Vcomp
  2538. if (%comp%)==(EQ) echo %1 was created or updated today
  2539. set comp=
  2540.  
  2541.  
  2542. :31 Compare two files' date/time using COMPARE-FUNCTION ERRORLEVELS
  2543. :==================================================================
  2544. COMMENT
  2545. There are many ways to check errorlevels.  This example shows 
  2546. several of them.
  2547.  
  2548. @echo off
  2549. cls
  2550. SET F1=FDATE.BAT
  2551. SET F2=FDATE.EXE
  2552. fdate /FTcomp /If /A%f1%  /B%F2% /P"%f1% is " /S" %f2%"
  2553.  
  2554. if errorlevel 101 if not errorlevel 103 echo %f1% is LT/EQ %f2%
  2555. if errorlevel 102                       echo %f1% is GT/EQ %f2%
  2556.  
  2557. if errorlevel 101 if not errorlevel 102 echo %f1% is older than %f2%
  2558. if errorlevel 102 if not errorlevel 103 echo %f1% is same age as %f2%
  2559. if errorlevel 103 if not errorlevel 104 echo %f1% is younger than %f2%
  2560.  
  2561. if errorlevel 101 if not errorlevel 103 echo %f1% at least as old as %f2%
  2562. if errorlevel 102                       echo %f1% is no older than %f2%
  2563.  
  2564. if errorlevel 101 if not errorlevel 102 echo errorlevel is 101
  2565. if errorlevel 102 if not errorlevel 103 echo errorlevel is 102
  2566. if errorlevel 103 if not errorlevel 104 echo errorlevel is 103
  2567. SET F1=
  2568. SET F2=
  2569. :endit
  2570.  
  2571.  
  2572.  
  2573. :32 Display a list of all files that were created/updated today. 
  2574. :==================================================================
  2575. @echo off
  2576. if (%1)==(SUBROUTINE) goto %2
  2577.  
  2578. CLS
  2579. ECHO FILES MEETING FILESPEC [%1] THAT WERE CREATED OR UPDATED TODAY
  2580. REM  The batch file calls itself: Its own name is in parm %0
  2581. for %%v in (%1) do  CALL %0 SUBROUTINE CHECKFILE %%v
  2582.  
  2583. set comp=
  2584. goto endit
  2585.  
  2586. :CHECKFILE
  2587. shift
  2588. shift
  2589.  
  2590. rem Compare today's date to the date on the %1 file
  2591. Fdate /Fcomp /If /A%1 /Vcomp  
  2592.  
  2593. rem echo the filename if the file was created/updated today
  2594. if (%comp%)==(EQ) echo %1
  2595. :endit
  2596.  
  2597. :33 Delete files more than X days old (use a batch-file subroutine)
  2598. :==================================================================
  2599. See the COMMENTARY that follows the text of the batch file.
  2600.  
  2601.  
  2602. @echo off
  2603. if (%1)==(SUBROUTINE) goto %2
  2604. cls
  2605.  
  2606. goto EndDoc
  2607. ----------------------------------------------------------------------
  2608. OLDFILES.BAT
  2609. This batch file shows how to do work on files that are older than
  2610. %NumDays%.  The PROCESS! subroutine can be modified to do any kind of
  2611. work you want.
  2612. ----------------------------------------------------------------------
  2613. :EndDoc
  2614.  
  2615. :: set the number of days in the past.   if this value is not passed
  2616. :: in via parameter %1, it defaults to 3 days
  2617. set NumDays=%1
  2618. if (%NumDays%)==() SET NumDays=3
  2619.  
  2620.  
  2621. echo ------------------------------------------------------------------
  2622. echo           PROCESSING FILES CREATED MORE THAN %NumDays% DAYS AGO
  2623. echo ------------------------------------------------------------------
  2624. for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2625. echo ------------------------------------------------------------------
  2626. echo           END OF PROCESSING
  2627. echo ------------------------------------------------------------------
  2628.  
  2629. :: CLEANUP
  2630. set NumDays=
  2631. set DaysOld=
  2632. set Comparison=
  2633. GOTO ENDIT
  2634.  
  2635. :
  2636. :PROCESS!
  2637. shift
  2638. shift
  2639.  
  2640. :: get difference in days between filedate and today.
  2641. :: Note that /B parm (which is omitted) defaults to today's date.
  2642. fdate /fdif   /A%1        /IF          /VDaysOld
  2643.  
  2644. :: compare DaysOld to NumDays
  2645. fdate /f#comp /A%DaysOld% /B%NumDays%  /Vcomparison
  2646.  
  2647. :: the following line will DISPLAY THE NAME AND AGE OF
  2648. :: any file for which %DaysOld% is greater than %NumDays%
  2649. :: --------------------------------------------------------------
  2650. if (%comparison%)==(GT) echo %1 is %DaysOld% days old.
  2651.  
  2652. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2653. :: the following line will COPY TO AN ARCHIVE SUBDIRECTORY
  2654. :: any file for which %DaysOld% is greater than %NumDays%
  2655. :: -----------------------------------------------
  2656. REM if (%comparison%)==(GT) COPY %1 C:\ARCHIVE\*.*
  2657.  
  2658. :: EXAMPLE (to activate this routine, remove the REM from column 1)
  2659. :: the following line will DELETE
  2660. :: any file for which %DaysOld% is greater than %NumDays%
  2661. :: -----------------------------------------------
  2662. REM if (%comparison%)==(GT) DEL %1
  2663.  
  2664. :: fall through to endit
  2665.  
  2666. :endit
  2667.  
  2668.  ===============================================================
  2669.                         COMMENTARY BEGIN
  2670.  ===============================================================
  2671.  This batch file uses a crude, but effective, technique for giving a
  2672.  batch file the ability to call subroutines.  If you've never seen
  2673.  something like this before, it is sort of mind-blowing.  Here's some
  2674.  commentary on the more important lines involved in the technique.
  2675.  ===============================================================
  2676.  
  2677.  if (%1)==(SUBROUTINE) goto %2
  2678.  
  2679.     COMMENTARY:
  2680.     If the first parameter, %1, is "SUBROUTINE", then the batch file
  2681.     recognizes that it is being called for the purpose of executing
  2682.     one of its own subroutines.  In such a case, it does a GOTO to the
  2683.     start of the requested subroutine.  That is, it goes to the label
  2684.     whose name is in the second parameter.
  2685.  
  2686.     Explicitly specifying the name of the desired subroutine permits
  2687.     permits us to have multiple subroutines in the batch file,
  2688.     each with its own name.  (As it happens, in this batch file
  2689.     we have only one subroutine, named "PROCESS!")
  2690.  
  2691.     If the first parameter is not "SUBROUTINE", then we fall through
  2692.     and begin executing the main routine of the batch file.  In such a
  2693.     case, the first parameter (%1) may contain a number, indicating
  2694.     the number of days to use in determining which files to delete.
  2695.  
  2696.     Note that this technique will make the batch file malfunction
  2697.     if the user himself ever executes the batch file from the
  2698.     DOS command line with the word "SUBROUTINE" as the first
  2699.     parameter, the word "PROCESS!" as the second parameter, and a
  2700.     third parameter that is missing or not a valid filename.
  2701.     This is so unlikely, however, that it is reasonable
  2702.     to assume that it will never happen.
  2703.  
  2704.  ===============================================================
  2705.  
  2706.  for %%v in (*.*) do  CALL %0 SUBROUTINE PROCESS! %%v
  2707.  
  2708.     COMMENTARY:
  2709.     In a batch file, %0 contains the name by which the batch file was
  2710.     invoked.  We use this fact to allow a batch file to call itself,
  2711.     regardless of what name the user has given to it.
  2712.  
  2713.     The first parameter passed, when the batch file calls
  2714.     itself, is the string "SUBROUTINE".  This string allows the batch
  2715.     file to recognize when it is being called for the purpose of
  2716.     executing one of its own subroutines.
  2717.  
  2718.     The second parameter is the name of the subroutine that we want
  2719.     to call: in this case, "PROCESS!".
  2720.  
  2721.     The third parameter is what we would normally think of as the first
  2722.     parameter to the subroutine.  In this case, when the
  2723.     FOR statement is executed, and the substitution for %%v takes
  2724.     place, it will contain the name of the file to be processed.
  2725.     Note that we could, if we wished, pass additional parameters to
  2726.     the subroutine.  Note also that we can control the files that
  2727.     we process.  We do so via the filemask in the FOR statement.
  2728.     It we used, for example, "*.EXE", then we would process only
  2729.     executable files.
  2730.  
  2731.  ===============================================================
  2732.  
  2733.  GOTO ENDIT
  2734.  
  2735.    COMMENTARY:
  2736.    When the mainline of the batch file is finished executing, we
  2737.    goto the end of the batch file.  We MUST do this GOTO in order
  2738.    to avoid falling through into, and starting to execute, the first
  2739.    of the batch file's subroutines.
  2740.  
  2741.  ===============================================================
  2742.  
  2743.  :PROCESS!
  2744.  shift
  2745.  shift
  2746.  
  2747.    COMMENTARY:
  2748.    Note that when the batch file is called as a subroutine, and the
  2749.    batch file goes to the PROCESS! label, the values of the parms are:
  2750.            %0 = [the name of the batch file]
  2751.            %1 = SUBROUTINE
  2752.            %2 = PROCESS!
  2753.            %3 = [name of the file to be processed]
  2754.  
  2755.     We shift all the parameters to the left twice, to move the
  2756.     parameter(s) into what we think of as the
  2757.     proper places for parameters to the subroutine.
  2758.  
  2759.     After the first SHIFT command:
  2760.            %0 = SUBROUTINE
  2761.            %1 = PROCESS!
  2762.            %2 = [name of the file to be processed]
  2763.  
  2764.     After the second SHIFT command:
  2765.            %0 = PROCESS!
  2766.            %1 = [name of the file to be processed]
  2767.  
  2768.     Now %1 contains what we think of as the proper parameter(s)
  2769.     to the subroutine.  In this case, %1 contains the filename that
  2770.     we want the subroutine to process.
  2771.  
  2772.     At the end of every subroutine, there should be a GOTO ENDIT,
  2773.     which causes the batch file to go to its own end, and then
  2774.     end and return control to the statement in the program which called
  2775.     it.  (This is, of course, the CALL statement embedded in the
  2776.     FOR statement.)
  2777.  
  2778.     We can optimize the batch file a little by omitting the "goto endit"
  2779.     at the end of the last subroutine.  Instead, we simply allow the
  2780.     last subroutine to fall through to the end of the batch file.
  2781.  
  2782.  ===============================================================
  2783.                          COMMENTARY END
  2784.  ===============================================================
  2785.  
  2786. :34 Get date to tell PKZIP to compress files older than 30 days
  2787. :======================================================================
  2788. PKZIP (a popular file-compression utility) can be used to compress and
  2789. archive files that are older/younger than a given date.  To run PKZIP on
  2790. files that are, for example, older than 30 days, we need the date that was
  2791. 30 days before today's date.  To get it, we use Fdate to subtract 30 days
  2792. from today's date, and put that date out in PKZIP's "American" format
  2793. (MMDDYY). (Fdate also supports PKZIP's Japanese and European formats.)
  2794.  
  2795. To compress all files that were created before a date 30 days ago:
  2796.  
  2797.      Fdate /Fsub /N30 /Ommddyy /VArchiveDate
  2798.      pkzip test.zip -T%ArchiveDate%
  2799.  
  2800. For more information, see PKZIP's MANUAL.DOC file.
  2801.  
  2802. :40 Loop through an array of environment variables
  2803. :======================================================================
  2804. @echo off
  2805. cls
  2806. SET pct=%%%
  2807. SET prefix=Address
  2808.  
  2809. ECHO LOADING AN ARRAY
  2810. SET subscript=1
  2811. SET %prefix%.%subscript%=Stephen Ferg
  2812. SET subscript=2
  2813. SET %prefix%.%subscript%=5113 N. 8th Road
  2814. SET subscript=3
  2815. SET %prefix%.%subscript%=Arlington, VA 22205
  2816.  
  2817. ECHO UNLOADING AND DISPLAYING THE ARRAY
  2818. SET subscript=1
  2819. :LoopTop
  2820. REM do while subscript less than/equal 3
  2821. if %subscript%==4 goto LoopEnd
  2822.  
  2823.    REM put value of subscripted variable into tempvar
  2824.    ECHO SET tempvar=%pct%%prefix%.%subscript%%pct%>JUNKTEMP.BAT
  2825.    CALL JUNKTEMP.BAT
  2826.  
  2827.    REM display value of subscripted variable
  2828.    ECHO %prefix%.%subscript% is: %tempvar%
  2829.  
  2830.    REM delete subscripted variable
  2831.    SET %prefix%.%subscript%=
  2832.  
  2833.    REM increment the loop variable
  2834.    Fdate /F#add /A%subscript% /B1 /Vsubscript
  2835.    goto LoopTop
  2836. :LoopEnd
  2837.  
  2838. SET pct=
  2839. SET tempvar=
  2840. SET prefix=
  2841. SET subscript=
  2842. DEL JUNKTEMP.BAT
  2843.  
  2844. :44 Do something on the last day (or last Friday) of the month
  2845. :==================================================================
  2846. COMMENT
  2847. We often need batch files that do some special task on the last day of the
  2848. month: run a backup job, display a reminder message, etc.  This example
  2849. batch file, LASTDAY.BAT, simply displays a message -- you can modify it to
  2850. do whatever it is that YOU want to do.
  2851.  
  2852. If you plan to run LASTDAY.BAT at work, and you work Monday through Friday,
  2853. then checking for the last day of the month would be a poor strategy --
  2854. after you leave work on a Friday, the last day of the month might occur on
  2855. the following Saturday or Sunday.   So I've included a check to see if the
  2856. Friday is the last working day of the month.  If you don't want that
  2857. functionality, deleting the lines between the first and last occurrence of
  2858. the string "EndCheck" will remove it.
  2859. =======================================================================
  2860.  @echo off
  2861.  REM ---------------------------------------------------------------
  2862.  REM check to see if today is the last day of the month
  2863.  REM ---------------------------------------------------------------
  2864.  REM get today's month
  2865.  fdate /ff        /omm /vmmtoday
  2866.  
  2867.  REM get tomorrow's month
  2868.  fdate /fadd /n1 /omm  /vmmtomorrow
  2869.  
  2870.  REM if tomorrow occurs in a different month,
  2871.  REM then today is the last day of this month
  2872.  if not (%mmtoday%)==(%mmtomorrow%) echo LAST DAY OF THE MONTH
  2873.  if not (%mmtoday%)==(%mmtomorrow%) goto EndCheck
  2874.  
  2875.  REM -------------------------------------------------------------
  2876.  REM check to see if today is the last Friday of the month
  2877.  REM -------------------------------------------------------------
  2878.  rem get today's day of the week, to see if it is Friday
  2879.  fdate /ff /odow3 /vdow3
  2880.  if not (%dow3%)==(Fri) goto EndCheck
  2881.  
  2882.  REM today is Friday.  Get next Monday's month
  2883.  fdate /fadd /n3 /omm  /vmmMonday
  2884.  
  2885.  REM if next Monday occurs in a different month,
  2886.  REM then today is the last Friday of this month
  2887.  if not (%mmtoday%)==(%mmMonday%) echo LAST WORKING DAY OF THE MONTH
  2888.  
  2889.  :EndCheck
  2890.  
  2891.  REM cleanup
  2892.  set dow3=
  2893.  set mmtoday=
  2894.  set mmtomorrow=
  2895.  set mmMonday=
  2896.  
  2897. :45 Get information about the month prior to the current month
  2898. :==================================================================
  2899. COMMENT
  2900. When running a monthly backup job at the beginning of the month, one often
  2901. needs to identify the previous month, or the last day of the previous
  2902. month.  Here's how to use Fdate to obtain that sort of information. 
  2903. Basically, we subtract one day from the first day of the current month,
  2904. giving us the last day of the previous month.
  2905. =======================================================================
  2906. @echo off
  2907. cls
  2908. : The simplest way to get information about last month is to subtract
  2909. : 1 day from the first day of this month ...
  2910.  
  2911. fdate /fsub /n1 /att-01-tttt /omm   /p"Last month was.................: "
  2912. fdate /fsub /n1 /att-01-tttt /occyy /p"Last month occurred in the year: "
  2913. fdate /fsub /n1 /att-01-tttt /odd   /p"The last day of last month was : "
  2914. fdate /fsub /n1 /att-01-tttt /od1   /p"The last day of last month was : "
  2915.  
  2916.  
  2917.  
  2918. :46 Show the last Monday (or any other weekday) in this month
  2919. :==================================================================
  2920. @echo off
  2921. cls
  2922. :: Use monthly arithmetic to get first day of next month
  2923. fdate /fm /n1 /att-01-tttt /omm-dd-ccyy   /v
  2924.  
  2925. :: get the preceding Monday, i.e. the last Monday in this month
  2926. fdate /fw /d2 /n-1 /x /a%fdate%
  2927.  
  2928. :47 Show the last Monday in the month, for a series of months
  2929. :==================================================================
  2930. @echo off
  2931. cls
  2932. :: initialize constants
  2933. set StartDate=01-01-1996
  2934. set MONTHS=15
  2935.  
  2936. echo Show the last Mondays in the month,
  2937. echo for the %months% months starting %StartDate%
  2938. echo ==============================================================
  2939.  
  2940. set COUNT=1
  2941. :LOOPTOP
  2942.   :: compare COUNT to MONTHS, exit loop if COUNT exceeds MONTHS
  2943.   FDATE /F#comp /A%COUNT% /B%MONTHS% /vCOMP
  2944.   if (%COMP%)==(GT) goto ENDLOOP
  2945.  
  2946.   :: Use monthly arithmetic to get first day of next month
  2947.   FDATE /Fm /N%COUNT% /A%StartDate% /Omm-dd-ccyy   /Vfdate
  2948.  
  2949.   :: get the preceding Monday (/D2) -- the last Monday in this month
  2950.   FDATE /Fw /D2 /N-1 /X /A%fdate% /P"%count% "
  2951.  
  2952.   :: increment COUNT
  2953.   FDATE /F#add /A%COUNT% /B1 /Vcount
  2954.   GOTO LOOPTOP
  2955. :ENDLOOP
  2956. echo.
  2957.  
  2958. :endit
  2959. set StartDate=
  2960. set MONTHS=
  2961. set COUNT=
  2962. set COMP=
  2963. set FDATE=
  2964.  
  2965. :50 Represent a date in 3 bytes of "extended hex" notation
  2966. :==================================================================
  2967.  
  2968. rem produce today's date as 3 bytes
  2969. fdate /ff /oxxx 
  2970.  
  2971. rem produce yesterday's date in xxx format
  2972. fdate /fsub /N1 /oxxx
  2973.  
  2974.  
  2975.  
  2976.  
  2977. :51 Represent a date in a short (4-byte) format (technique #1)
  2978. :==================================================================
  2979. COMMENT
  2980. A common use of Fdate is to format today's date and use it to rename a file
  2981. (typically a log file of some sort).  You may wish to store the date
  2982. information in as few characters as possible, in order to maximize the
  2983. number of other characters in the filename that you can use to store other
  2984. information.
  2985.  
  2986. In this example, and the next one, I illustrate two ways to store a date in
  2987. 4 bytes.
  2988.  
  2989.  
  2990. The simplest way is to represent today's date as a 4-digit number.
  2991. To do this, we first pick a base date:  I'll use January 1, 1990.
  2992. Then it is a simple matter to calculate the number of days between today
  2993. and the base date:
  2994.  
  2995.            FDATE /Fdif /at /b01-01-1990 
  2996.  
  2997. Starting in 1993, this will always generate a 4-digit number, and will
  2998. continue to do so for 20 years, until approximately the year 2003.  Dates
  2999. before 1993 may produce 1-, 2-, or 3-digit numbers, and dates after 2003
  3000. will begin to produce 5-digit numbers.  But this technique will work quite
  3001. nicely for most ordinary purposes for the next 20 years.  
  3002.  
  3003. If you're still using DOS in the year 2003, then in 2003 you can switch to
  3004. using January 1, 2000 as your base date and function quite nicely for the
  3005. next 20 years after that.
  3006.  
  3007. :52 Represent a date in a short (4-byte) format (technique #2)
  3008. :==================================================================
  3009. @echo off
  3010. cls
  3011. goto end-doc
  3012. ------------------------------------------------------------------
  3013. This batch file shows how to use Fdate's #2XX function to
  3014. obtain and represent today's date in 4 characters, YYMD, where:
  3015.  
  3016.   YY is the year (e.g. "93" for 1993)
  3017.    M is the month in extended hexadecimal (XX) notation
  3018.    D is the day-of-the-month in extended hexadecimal (XX) notation
  3019.  
  3020. You can also use Fdate's "XXX" output format to represent dates between
  3021. 1990 and 2024 in 3 bytes of extended hex notation.
  3022. ------------------------------------------------------------------
  3023. :end-doc
  3024.  
  3025. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE MONTH
  3026. Fdate /ff    /Omm   /Vmm
  3027. Fdate /f#2xx /A%mm% /Vmm
  3028. echo XX representation of this month's number      is %mm%
  3029.  
  3030. REM OBTAIN 1-CHARACTER REPRESENTATION FOR THE DAY
  3031. Fdate /ff    /Odd   /Vdd
  3032. Fdate /f#2xx /A%dd% /Vdd
  3033. echo XX representation of today's day of the month is %dd%
  3034.  
  3035. REM CONCATENATE THEM TO THE 2-CHARACTER REPRESENTATION FOR THE YEAR
  3036. Fdate /Ff /Oyy /S%mm%%dd% /Vdate
  3037. echo XX representation of today's full date        is %date%
  3038.  
  3039. REM CLEANUP
  3040. set mm=
  3041. set dd=
  3042. set date=
  3043. :endit
  3044.  
  3045.  
  3046.  
  3047. :53 Convert numbers to "extended hex" (XX) format
  3048. :==================================================================
  3049. @echo off
  3050. cls
  3051. SET decnum=0
  3052. :top
  3053.    if (%decnum%)==(37) goto endit
  3054.    fdate /f#2xx /A%decnum% /P"XX representation of %decnum% is "
  3055.    fdate /f#add /A%decnum% /b1 /Vdecnum
  3056. goto top
  3057.  
  3058. :endit
  3059.  
  3060. :54 Customize Fdate for a language of your choice
  3061. :==================================================================
  3062. @echo off
  3063. cls
  3064. goto end-doc
  3065. ------------------------------------------------------------------
  3066. You can use Fdate with a customized batch file to obtain the names of
  3067. the days of the week and the months in a language of your choice.  Or
  3068. you could use it to obtain names in uppercase, or the first 5
  3069. characters of the names (rather than the first three), or some other
  3070. customized formatting of your choice.)
  3071.  
  3072. I've invented a language called Fergian, which has its own names for
  3073. the days of the week, and the months.  In the following examples, I
  3074. invoke FERGIAN.BAT to make the translation.  The text of FERGIAN.BAT,
  3075. which does the real work here, is given in the next example.
  3076. ------------------------------------------------------------------
  3077. :end-doc
  3078.  
  3079. fdate /ff /omm /v
  3080. call Fergian mm- result %Fdate%
  3081. echo Month  is          %result%
  3082.  
  3083. fdate /ff  /omm /v
  3084. call Fergian mm3 result %Fdate%
  3085. echo Month3 is          %result%
  3086.  
  3087. fdate /ff /odow#  /v
  3088. call Fergian dw- result %Fdate%
  3089. echo Day of week  is    %result%
  3090.  
  3091. fdate /ff /odow#  /v
  3092. call Fergian dw3 result %Fdate%
  3093. echo Day of week3 is    %result%
  3094.  
  3095. REM cleanup
  3096. set Fdate=
  3097. set result=
  3098.  
  3099. :55 Fergian.BAT (used in the previous example)
  3100. :==================================================================
  3101. @echo off
  3102. set  %2=
  3103. goto %1
  3104.  
  3105. goto end-doc
  3106. --------------------------------------------------------------------
  3107. This batch file converts a month number, or day of the week number,
  3108. to a name in the FERGIAN language.
  3109. You can copy this batch file and customize it, to make it translate
  3110. into some other language of your choice.
  3111.  
  3112. This batch file expects the following parameters:
  3113.  
  3114. %1 contains the type of number you want to convert:
  3115.    MM- if you want the entire name of the month
  3116.    MM3 if you want the first 3 letters of the name of the month
  3117.  
  3118.    DW- if you want the entire name of the day of the week
  3119.    DW3 if you want the first 3 letters of the name of the day of the week
  3120.  
  3121. %2 contains the name of the environment variable that you
  3122.    want to use to hold the result
  3123.  
  3124. %3 contains the number that you want to convert
  3125. --------------------------------------------------------------------
  3126. :end-doc
  3127.  
  3128. :MM-
  3129. if (%3)==(01) set %2=Jaded
  3130. if (%3)==(02) set %2=Febrile
  3131. if (%3)==(03) set %2=Martial
  3132. if (%3)==(04) set %2=Abigail
  3133. if (%3)==(05) set %2=Maybelene
  3134. if (%3)==(06) set %2=Junkaroo
  3135. if (%3)==(07) set %2=Julia
  3136. if (%3)==(08) set %2=Augmentation
  3137. if (%3)==(09) set %2=Separation
  3138. if (%3)==(10) set %2=Ostentation
  3139. if (%3)==(11) set %2=Novelty
  3140. if (%3)==(12) set %2=Decadence
  3141. goto endit
  3142.  
  3143. :
  3144. :MM3
  3145. if (%3)==(01) set %2=Jad
  3146. if (%3)==(02) set %2=Feb
  3147. if (%3)==(03) set %2=Mar
  3148. if (%3)==(04) set %2=Abi
  3149. if (%3)==(05) set %2=May
  3150. if (%3)==(06) set %2=Jun
  3151. if (%3)==(07) set %2=Jul
  3152. if (%3)==(08) set %2=Aug
  3153. if (%3)==(09) set %2=Sep
  3154. if (%3)==(10) set %2=Ost
  3155. if (%3)==(11) set %2=Nov
  3156. if (%3)==(12) set %2=Dec
  3157. goto endit
  3158.  
  3159. :DW-
  3160. if (%3)==(1) set %2=SunDay
  3161. if (%3)==(2) set %2=MoonDay
  3162. if (%3)==(3) set %2=TwickasDay
  3163. if (%3)==(4) set %2=WodensDay
  3164. if (%3)==(5) set %2=ThorsDay
  3165. if (%3)==(6) set %2=FreyasDay
  3166. if (%3)==(7) set %2=SaturnDay
  3167. goto endit
  3168.  
  3169.  
  3170. :DW3
  3171. if (%3)==(1) set %2=Sun
  3172. if (%3)==(2) set %2=Moo
  3173. if (%3)==(3) set %2=Twi
  3174. if (%3)==(4) set %2=Wod
  3175. if (%3)==(5) set %2=Tho
  3176. if (%3)==(6) set %2=Fre
  3177. if (%3)==(7) set %2=Sat
  3178. goto endit
  3179.  
  3180. :endit
  3181.  
  3182. :61 DO-ONCE: Run apps when booting for the first time of the day
  3183. :===============================================================
  3184. COMMENT
  3185.   Put this code in AUTOEXEC.BAT.  Note that this batch code requires DOS
  3186.   3.3+, since it uses CALL.
  3187.  
  3188. if not exist C:\LASTRUN.BAT goto RunNow
  3189.  
  3190. rem call LASTRUN.BAT, which will set an environment variable, %LASTRUN%,
  3191. rem that will contain the date when this batch file was last run.
  3192. rem ------------------------------------------------------------------
  3193. call C:\LASTRUN.BAT
  3194.  
  3195. rem compare the date in %LASTRUN% to today's date
  3196. rem ------------------------------------------------------------------
  3197. Fdate /Fcomp /At /B%LastRun% /Vcomp
  3198.  
  3199. : Today's date may be less than %LASTRUN% if you reset the system clock
  3200. IF (%COMP%)==(LT) goto NoRun
  3201. : If %LASTRUN% was the same as today's date,
  3202. :   then this batch file has already been run once today
  3203. IF (%COMP%)==(EQ) goto NoRun
  3204.  
  3205. : Daily processing hasn't been run today. Run it.
  3206. : Here, you should put the batch-file body --
  3207. : the code to run the applications that you want to run once per day
  3208. :
  3209.  
  3210. : ------------------------------------------------------------------
  3211. : Save today's date in a new version of LastRun.BAT.  Note that
  3212. : this code will be executed only if daily processing runs to
  3213. : completion without hanging the machine or aborting the batch file.
  3214. : ------------------------------------------------------------------
  3215. Fdate /Ff /Omm-dd-ccyy /At /P"@set LastRun=">LastRun.BAT
  3216.  
  3217. :NoRun
  3218. set LastRun=
  3219. set COMP=
  3220.  
  3221. :62 Run specific software, depending on the day of the week
  3222. :==================================================================
  3223. COMMENT
  3224. This is a very common use for Fdate.  I use it to load an alarm-clock TSR
  3225. (Terminate and Stay Resident, "memory resident", program) that beeps at me
  3226. (at different times on different days of the week) to remind me that it is
  3227. time to attend a meeting that is regularly scheduled for that day of the
  3228. week.
  3229.  
  3230. Note that stuff for a given day of the week will be executed every time you
  3231. boot up on that day of the week.  If you want stuff (e.g. a backup job) to
  3232. be run only once (the first time you boot up) on a given day of the week,
  3233. then:
  3234.  
  3235. (1)  copy the code from DO-ONCE (the previous example) into your
  3236.      AUTOEXEC.BAT file, then
  3237.  
  3238. (2)  copy this code into the body of the DO-ONCE code that you copied into
  3239.      AUTOEXEC.BAT in the last step.  If you do that, then this code will be
  3240.      run only once per day, even if you boot up multiple times per day.
  3241.  
  3242. Remember that if you are executing other batch files from a batch file, 
  3243. you should invoke them with a CALL statement:
  3244.               CALL batchfilename parm1 parm2 ...
  3245. so control will return to the calling batch file when execution of the
  3246. called batch file is complete.      
  3247.  
  3248. Note that the string comparison is case sensitive.
  3249. ==================================================================
  3250.  
  3251. :: get 3-character day-of-week name and put it in DOW e-var
  3252. FDATE /ff /oDOW3 /vDOW
  3253.  
  3254. if (%DOW%)==(Mon) alarmTSR.exe 10:30 Time for Monday staff meeting
  3255.  
  3256. if (%DOW%)==(Fri) echo Running Friday backup.  Please wait...
  3257. if (%DOW%)==(Fri) CALL BACKUP C: 
  3258. if (%DOW%)==(Fri) CALL BACKUP D: 
  3259. set dow=
  3260.  
  3261.  
  3262.  
  3263. :63 Run a program at a specified time later in the day
  3264. :==================================================================
  3265. COMMENT
  3266.   This batch file involves a lot of disk activity because DOS re-reads the
  3267.   batch file from disk every time it does a GOTO LOOPTOP.  You can avoid
  3268.   all this disk activity by running the batch file from a RAM DISK.
  3269.  
  3270. REM GET CURRENT ABSOLUTE MINUTE AND PUT IN ENVIRONMENT VARIABLE RUNTIME
  3271. FDATE /Ff /At /Ominute#  |STRINGS RunTime= ASK >NUL
  3272.  
  3273. REM ADD 120 MINUTES (2 HOURS) TO ENVIRONMENT VARIABLE RUNTIME
  3274. FDATE /F#add /A%RunTime% /B120 |STRINGS RunTime= ASK >NUL
  3275.  
  3276. REM LOOP UNTIL NOWTIME HAS REACHED RUNTIME
  3277. :LoopTop
  3278.   FDATE /Ff /At  /Ominute#   |STRINGS NowTime=  ASK >NUL
  3279.   FDATE /F#comp  /A%NowTime% /B%RunTime% |STRINGS TimeComp= ASK >NUL
  3280.   if (%TimeComp%)==(LT) goto loopTop
  3281. :LoopEnd
  3282.  
  3283. echo STARTING EXECUTION OF APPLICATION: [program name]
  3284.  
  3285.  
  3286.  
  3287. :66 Change a filename to contain today's date in first 3 bytes
  3288. :==================================================================
  3289. FDATE /Ff /Oxxx /vXXX
  3290. ren  BACKUP.LOG  %XXX%-BACK.LOG
  3291. SET  XXX=
  3292.  
  3293.  
  3294.  
  3295. :67 Change a file's name to a name that contains today's date
  3296. :==================================================================
  3297. :: today's date (/At) in CCYYMMDD format into environment variable DATE1
  3298. FDATE /Ff /At /Occyymmdd /Vdate1
  3299. :: rename BACKUP.LOG to ccyymmdd.LOG (ex. 19950508.LOG on May 8, 1995)
  3300. REN BACKUP.LOG  %date1%.LOG
  3301. SET DATE1=
  3302.  
  3303.  
  3304. :68 Change a file's name to a name containing an absolute minute 
  3305. :===============================================================
  3306. COMMENT
  3307.   This is a way to keep a complete series of files, such as log files,
  3308.   that are all created with the same name on the same day.  The only
  3309.   requirement is that they be created at least one minute apart.  You
  3310.   won't need to be able to decipher the absolute minute to figure out when
  3311.   the file was created; you can simply do a DIR on the file and look at
  3312.   its date/time stamp.  
  3313.  
  3314. FDATE /FF /At /Ominute# /VJulMin
  3315. REN online.log %JulMin%.log
  3316. SET JulMin=
  3317.  
  3318.  
  3319.  
  3320. :71 Extract the rightmost n characters of a string 
  3321. :===============================================================
  3322. rem extract the rightmost 6 characters of a string
  3323. FDATE /Fsubstr /a-6     /Q"1994 Jun 03"   ===> "Jun 03"     
  3324.  
  3325.  
  3326.  
  3327. :72 Left-pad a number with zeroes, or a string with spaces
  3328. :===============================================================
  3329. :: pad a number (stored in environment variable) STRING
  3330. :: to the left with zeroes, to make sure it is 4 bytes long
  3331. set STRING=1
  3332. Fdate /Fe  /P%STRING% /Jr04  /Vstring
  3333. echo STRING is [%string%]
  3334.  
  3335. :: pad a string (stored in environment variable) STRING
  3336. :: to the left with spaces, to make sure it is 4 bytes long
  3337. set STRING=aa
  3338. Fdate /Fe  /P%STRING% /J"r 4"  /Vstring
  3339. echo STRING is [%string%]
  3340.  
  3341. HOW FDATE THINKS ABOUT DATES
  3342. ============================
  3343.  
  3344. FDATE'S BUSINESS VIEW OF THE CALENDAR
  3345. =====================================
  3346.  
  3347.   FDATE is intended for business applications, not historical ones.  
  3348.  
  3349.   FDATE does not take into account historical changes in the calendar such
  3350.   as the ten days that were dropped from the British calendar when Britain
  3351.   moved from the Julian to the Gregorian calendar in the 18th century, or
  3352.   the 11 days that were dropped from the Russian calendar when Russia made
  3353.   the same move in the early 20th century.
  3354.  
  3355.   As far as FDATE is concerned, the calendar has followed the same
  3356.   pattern, unchanged, since January 1, 0001.
  3357.  
  3358.  
  3359. FDATE'S BASE DATE
  3360. =================
  3361.   Internally, Fdate's date manipulations are based on translating a
  3362.   calendar date into an "absolute" or "TRUE Julian" date:  a date
  3363.   expressed as the number of days from some day in the distant past.
  3364.  
  3365.   FDATE's base date is January 1, 0001 (i.e. day 1 of month 1 of year 1)
  3366.   FDATE's absolute date for January 1, 0001 is      1.
  3367.   FDATE's absolute date for January 1, 1992 is 727198.
  3368.  
  3369.  
  3370. FDATE'S LEAP YEAR ALGORITHM
  3371. ===========================
  3372.     Every year evenly divisible by 4 IS a leap year
  3373.       EXCEPT THAT
  3374.         Every year evenly divisible by 100 IS NOT a leap year
  3375.           EXCEPT THAT
  3376.             Every year evenly divisible by 400 IS a leap year
  3377.     .
  3378.     Using this algorithm
  3379.          1983  is not a leap year
  3380.          1984  is     a leap year
  3381.          1900  is not a leap year
  3382.          2000  is     a leap year
  3383.  
  3384.     See "A Machine Algorithm for Processing Calendar Dates", by
  3385.          Henry F. Fliegel (Georgetown University Observatory) and
  3386.          Thomas C. Van Flandern (U.S. Naval Observatory)
  3387.          COMMUNICATIONS OF THE ACM, Volume 11, Number 10, October 1968
  3388.  
  3389. There is supposedly a new adjustment to the leapyear algorithm,
  3390. which specifies the additional exception:
  3391.  
  3392.               EXCEPT THAT
  3393.                 Every year evenly divisible by 4000 IS a leap year
  3394.  
  3395. See "Bit By Bit" column, COMPUTER LANGUAGE, November 1989, p. 148.
  3396. This adjustment is not part of FDATE's leapyear algorithm.
  3397. Unless your application is working with dates 2,000 years in the
  3398. future, the lack of this exception will be irrelevant for you.
  3399.  
  3400. FDATE'S CENTURY-ASSUMPTION ALGORITHM
  3401. ====================================
  3402. If an input date is supplied in a format in which the year is
  3403. specified without a century -- that is, as YY rather than CCYY --
  3404. then Fdate does not automatically use the current century.
  3405. Instead,
  3406.  
  3407.    *  if YY is greater than 20,       then FDATE assumes CC = 19
  3408.    *  if YY is less than or equal 20, then FDATE assumes CC = 20
  3409.  
  3410. Examples:
  3411.          21    becomes  1921
  3412.          ...
  3413.          99    becomes  1999
  3414.          00    becomes  2000
  3415.          01    becomes  2001
  3416.          ...
  3417.          20    becomes  2020
  3418. but then (again)
  3419.          21    becomes  1921
  3420.  
  3421. To put it simply, FDATE makes what would be a reasonable assumption about
  3422. the century for someone operating in the 1990's: it looks back to 1921 and
  3423. forward to 2020.  If I, FDATE, and DOS are still alive in the year 2005
  3424. (which, given the introduction of Windows 95, seems unlikely) I'll probably
  3425. update FDATE's century-assumption algorithm to shift it forward several
  3426. decades.
  3427.  
  3428.  
  3429. FDATE'S IMPLEMENTATION LIMITS
  3430. ====================================
  3431. Internally, numbers in Fdate are stored in Turbo Pascal's LONGINT datatype,
  3432. which means that Fdate can accept numbers up to 9 digits long.
  3433.  
  3434. DISTRIBUTION ISSUES
  3435. ===================
  3436.  
  3437. USE, REGISTRATION, AND DISTRIBUTION OF FDATE
  3438. ============================================
  3439.  
  3440. FDATE is freeware, or what is known as "zero-cost shareware".  FDATE is not
  3441. what is technically called "public domain" software because the author
  3442. retains the copyright.  FDATE can, however, be copied, used, and
  3443. distributed freely as long as FDATE.EXE and its associated doc file
  3444. (FDATE.DOC) and demonstration batch files and doc files (HOLIDAYS.BAT,
  3445. HOLIFEDS.BAT, HOLIFEDS.DOC) are not altered and are distributed together.  
  3446.  
  3447. There is no requirement to register FDATE in any way.
  3448.  
  3449. FDATE can be included in shareware packages as long as both FDATE and
  3450. its related files are included in the shareware package.
  3451.  
  3452. If you have received FDATE as part of some larger shareware package,
  3453. please be aware that you may freely use, copy, and distribute FDATE
  3454. without paying a fee for, or registering, the larger package.
  3455.  
  3456. The author explicitly disavows any claim whatsoever about the
  3457. correctness or functionality of FDATE, its documentation, and its
  3458. demonstration batch files, and disclaims liability for anything and
  3459. everything bad that might happen in connection with, before, during, or
  3460. after using it.  I have tried to make FDATE work right, but everybody
  3461. makes mistakes, so you use FDATE at your own risk.
  3462.  
  3463. I don't know if people will find FDATE useful, and I'd like to find
  3464. out.  If you find FDATE useful and use it on a regular basis, I'd
  3465. appreciate it if you would drop me a short note via US mail or
  3466. CompuServe, telling me about how you are using FDATE.
  3467.  
  3468. If you need other input/output formats, please contact the author.
  3469.  
  3470.  
  3471. TECHNICAL SUPPORT FOR FDATE
  3472. ===============================================
  3473.  
  3474. Send me a message via CompuServe mail; I'll respond.  When sending your
  3475. message, please let me know what version of Fdate you're using.
  3476.  
  3477.  
  3478. WHERE TO FIND THE MOST CURRENT VERSION OF FDATE
  3479. ===============================================
  3480.  
  3481. You will always be able to find the most recent version of FDATE on
  3482. CompuServe.  The filename will be FDATE.ZIP, and it will be available in
  3483. the CIS:IBMSYS forum (library 1, the "DOS Utilities" library).
  3484.  
  3485. If you have problems finding it, try using cross-library searching, looking
  3486. for the filename FDATE.ZIP or the keyword FDATE.
  3487.  
  3488.  
  3489. UPLOADING FDATE TO ELECTRONIC BULLETIN BOARDS
  3490. ===============================================
  3491.  
  3492. Feel free to post copies of FDATE.ZIP on any BBS that you wish, but please
  3493. do not upload it to any CompuServe library.  As long as I am the only one
  3494. putting copies of FDATE onto CompuServe, we can keep confusion over
  3495. versions to a minimum.
  3496.  
  3497. I distribute all versions of FDATE in a files called FDATE.ZIP, rather than
  3498. embedding information about the version in the file name.  I think doing
  3499. this helps newer versions of FDATE to force older versions out of
  3500. circulation.  To give a BBS user information about the version, I always
  3501. identify the version of FDATE in the 1-line file description that most BBSs
  3502. support.  
  3503.  
  3504.  
  3505. CONTENTS OF THE FDATE.ZIP DISTRIBUTION FILE
  3506. ===========================================
  3507.  
  3508. The current distribution package (FDATE.ZIP) contains the following:
  3509.  
  3510.        FDATE.EXE         [the FDATE program]
  3511.        FDATE.DOC         [this file, documentation for FDATE]
  3512.        FDATEBEG.DOC      [FDATE beginners documentation]
  3513.  
  3514.   [demonstration batch files]
  3515.        HOLIDAYS.BAT
  3516.        HOLIFEDS.BAT and HOLIFEDS.DOC
  3517.  
  3518.   [documentation files for use in BBS distribution]
  3519.        FILE_ID.DIZ
  3520.        DESC.SDI  
  3521.  
  3522.  
  3523. RECENT FDATE REVISION HISTORY
  3524. =============================
  3525.  
  3526. Letters appended to version numbers indicate modifications to
  3527. the doc files, without any modification to the FDATE.EXE software.
  3528. Asterisks (*) indicate most important changes in the new version.
  3529.  
  3530. 7.0a   Nov 14, 1992
  3531.        Added #mod function
  3532.        Major reformatting of documentation to make it more user-friendly
  3533.    
  3534. 7.1a   Apr 15, 1993
  3535.        Added German language support.  Thanks for the request, and the
  3536.        necessary information, from Patrick Schmucki, via the Active-Net
  3537.        BBS in Rapperswil, Switzerland.
  3538.  
  3539. 8.0    July, 1993
  3540.        Added "V" (validate) and "m" (month addition/subtraction) functions
  3541.        Added math functions: #mult #div #idiv
  3542.        Added /T (time) parameter
  3543.  
  3544.        Added FORATIME.BAT example, which Walter Ledge (assistant sysop of
  3545.        CompuServe's CRFORUM) and I developed.  A big thanks to Walt for
  3546.        his feedback and help.
  3547.  
  3548. 8.1    July 27, 1993  BUG FIX
  3549.        An error-trapping routine that was added to version 7.9 contained a
  3550.        bug that caused Fdate's numeric math functions (#add, #dif, #mult,
  3551.        #div, #idiv, #mod, #comp, etc.) to return incorrect results. 
  3552.        
  3553. 8.2    August, 1993
  3554.        Removed FILEDATE.BAT from the distribution .ZIP file.
  3555.  
  3556.        Corrected the Spanish and French "full" and "d1" output formats. 
  3557.        Thanks for the information on Spanish and French date formats to
  3558.        Gene J. Raymond, of GJR Software Products.
  3559.  
  3560. 8.3a   Feb 24, 1994
  3561.  
  3562. *      Added the following string-handling functions:
  3563.        get    (get user input)
  3564.        getu   (get uppercase user input)
  3565.        upper  (uppercase a string)
  3566.        len    (length of a string)
  3567.        substr (substring)
  3568.  
  3569. *      Added /F#2xx (convert number to extended hex format) function. 
  3570.        Deleted SETXX.BAT, which has been made obsolete with the addition
  3571.        of this new function.  Modified second example of storing a 4-digit
  3572.        date to use #2xx instead of SETXX.BAT.
  3573.  
  3574. *      Added output formats "ddmmccyy" and "ddmmyy" at the request of
  3575.        several users.
  3576.  
  3577. *      Added output format "xxx" after several requests for advice on how
  3578.        to represent a large range of dates in a minimum number of bytes
  3579.        (usually for constructing filenames from today's date).
  3580.  
  3581. *      At the request of several users, enhanced the "compare" functions
  3582.        (comp, tcomp, #comp) so they set distinctive errorlevels for their
  3583.        different results.  See the table of contents ("COMPARE-FUNCTION
  3584.        ERRORLEVELS") and EXAMPLES.
  3585.  
  3586.        To discussion of /Fv parameter, added note about almost always
  3587.        redirecting output to NUL when using /Fv.
  3588.  
  3589.        Revised FORATIME.BAT example batch file to make error-correction a
  3590.        bit more robust and to add better documentation on how to use it.
  3591.  
  3592.        Added example batch files to use new functions, especially
  3593.        FORATIM2.BAT which uses new "get" function
  3594.  
  3595.        Removed FDATEX.BAT demonstration batch file from distribution
  3596.        package, to reduce its size.  The examples in this DOC file should
  3597.        make the examples in FDATEX.BAT unnecessary
  3598.  
  3599.  
  3600. 8.4a   March 20, 1994
  3601. *      Added GETK (get keypress) function
  3602.  
  3603. *      Added ability to use /V when running in a Windows DOS box, thanks
  3604.        to a Turbo Pascal routine from the Turbo Professional library
  3605.        provided by Kim Kokkonen of TurboPower Software.
  3606.  
  3607.        Fixed a bug in which the prompt string (/Q) for the GET and GETU
  3608.        functions was being written to redirectable output (StdOut).  The
  3609.        prompt string is now written directly to the screen, and will not
  3610.        appear in FDATE's output when the output is redirected to a file.
  3611.  
  3612.        Removed ALARM.BAT, ALARM.DOC, TIC.BAT and TIC.DOC from distribution
  3613.        package.  They were too esoteric to be generally helpful.
  3614.  
  3615.        Added FILE_ID.DIZ and DESC.SDI to distribution package.
  3616.  
  3617.        Corrected algorithm for Mardi Gras in HOLIDAYS.BAT.  Modified
  3618.        HOLIDAYS.BAT and HOLIFEDS.BAT to make them more interactive, using
  3619.        FDATE's new abilities to get user input.
  3620.  
  3621. *      Started ZIPing FDATE.ZIP with PKZIP 2.04g rather than version 1.1
  3622.  
  3623. 8.4b   April 2, 1994
  3624.        Revised example :08, to use /fgetK rather than /fgetU
  3625.        Fixed formatting of #dif function
  3626.        Reformatted examples to reduce number of printed pages
  3627.        Duplicate example :07 was renumbered 
  3628.        FORATIME.BAT (original version) removed as no longer interesting
  3629.        Modified JDATE.BAT to use new /Fget function
  3630.  
  3631. 8.4c   September 6, 1994
  3632.        Revised HOLIDAYS.BAT so it would not go into an infinite loop if
  3633.        run on a system where FDATE cannot manipulate the environment, and
  3634.        to pad the year to the left with zeroes, so years before 1000 will
  3635.        be accepted.
  3636.  
  3637.        Added example showing how to left-pad a number with zeroes.
  3638.  
  3639.        Rewrote example showing how to time execution of a program.
  3640.  
  3641.        Updated my home mailing address after moving.
  3642.  
  3643.        Corrected information on how to make sure you have enough
  3644.        environment space in a Windows DOS box.  Thanks for the feedback
  3645.        and on this issue from Ronny Richardson.
  3646.  
  3647.        Added WHATDAY.BAT (example :14).  Thanks for the request from Cal
  3648.        Pryluck, Radio-Television-Film, Temple University, Philadelphia
  3649.  
  3650. 8.5a   September 28, 1994
  3651.        Added output date format "mmddyy" (PKZIP's "American" date format),
  3652.        and an example showing how to use Fdate to get a date for use with
  3653.        PKZIP for archiving files.  Thanks for the tip on PKZIP's input
  3654.        formats from Dick Jensen.
  3655.  
  3656. 8.6a   October 27, 1994
  3657.        Corrected a bug in output format T1: HOUR value was being prefixed
  3658.        by a leading zero if MINUTE value was less than 10.
  3659.  
  3660. 8.7a   October 27, 1994
  3661.        Added output format TDOS, which mimics the format used in the DOS
  3662.        "time" command.  Added an example using it to the "roll your own"
  3663.        date format example (:19) as example (a).  Thanks for the request
  3664.        for this common time format from Roy Zider.
  3665.  
  3666. 8.8a   November 06, 1994
  3667.        Changed error action in cases in which the prefix parm /P was
  3668.        specified.  In case of an error, the first line generated will
  3669.        always be "ERROR".  If prefix parm was specified, then a second
  3670.        line will be generated with the prefix followed by "ERROR".  Thus,
  3671.        if output is being routed to a batch file, and the prefix is
  3672.        something like "@set fdate=", then that will continue to work.
  3673.  
  3674.        Removed the example of using /Fe to put equal-signs and redirection
  3675.        symbols into the environment.  I doubt if anyone found this example
  3676.        useful.
  3677.  
  3678.        Added ability to break out of HELP using the ESC key
  3679.  
  3680. *      Added justify parm (/J)
  3681.        Re-wrote HOLIDAYS.BAT to illustrate uses for /J.
  3682.  
  3683. 8.9a   1995 Feb 15
  3684. *      Added "absolute month" output format (/Omonth#)
  3685.        Added example YMD_DIF.BAT, which uses new /Omonth# facility
  3686.        Added FDATEBEG.DOC to the distribution .ZIP file
  3687.  
  3688. 9.0a   1995 Feb 20
  3689.        prefixed "@" to the "echo ERROR ... " and "pause" that are
  3690.        generated when Fdate detects an error.  This should make error
  3691.        messages a bit easier to decipher.
  3692.  
  3693. 9.1a   1995 May 15
  3694.        Corrected bug that gave runtime error when function was #mult and
  3695.        /A parm was 0.
  3696.  
  3697. 9.1b   1995 June 12
  3698.        Corrected example of Japanese date format in this DOC file.  Thanks
  3699.        to Christopher Clark for pointing out the typo.
  3700.  
  3701. 9.1c   1995 Oct 22
  3702.        Added a usage example to the discussion of the "file" input format
  3703.        (/If).  Thanks to Bob Stephan for the suggestion.
  3704.  
  3705. 9.1d   1995 Dec 08
  3706.        Added comments to example :67 (putting date into filename) and
  3707.        changed output format to ccyymmdd.  Hopefully, these changes will
  3708.        make this popular example more useful and easier to understand.
  3709.  
  3710. 9.2a   1996 Jan 28
  3711. *      Added /X (exclude) parm to /Fw (weekday arithmetic function). 
  3712.        Added appropriate documentation, and examples :46 and :47.  Thanks
  3713.        to Richard Rogers for a real-life application that required this
  3714.        feature.
  3715.  
  3716. 9.2b   1996 Feb 1
  3717.        Rectified a minor documentation omission; I'd forgot to add /X to
  3718.        the overview list of FDATE parms. 
  3719.        Expanded FDATEBEG.DOC by adding the overview of things you can do
  3720.        with FDATE.
  3721.  
  3722. 9.3a   1996 Apr 19
  3723.        Added output format mmddccyy.
  3724.        Added information on using Fdate with Windows NT.
  3725.        Added specific information on Garrett Wolman's FDATE.
  3726.  
  3727.